Source Code
Multichain Info
N/A
Latest 16 from a total of 16 transactions
| Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
| Force New Epoch | 13742968 | 2 days ago | IN | 0 ETH | 0.00000026 | ||||
| Force New Epoch | 13224375 | 8 days ago | IN | 0 ETH | 0.00000026 | ||||
| Force New Epoch | 12696301 | 14 days ago | IN | 0 ETH | 0.00000026 | ||||
| Force New Epoch | 12416538 | 18 days ago | IN | 0 ETH | 0.00000026 | ||||
| Force New Epoch | 12061479 | 22 days ago | IN | 0 ETH | 0.00000026 | ||||
| Force New Epoch | 10874511 | 35 days ago | IN | 0 ETH | 0.00000026 | ||||
| Force New Epoch | 10458757 | 40 days ago | IN | 0 ETH | 0.00000026 | ||||
| Force New Epoch | 10108827 | 44 days ago | IN | 0 ETH | 0.00000041 | ||||
| Force New Epoch | 9794036 | 48 days ago | IN | 0 ETH | 0.00000028 | ||||
| Force New Epoch | 9512405 | 51 days ago | IN | 0 ETH | 0.00000026 | ||||
| Force New Epoch | 9245970 | 54 days ago | IN | 0 ETH | 0.00000026 | ||||
| Force New Epoch | 8911418 | 58 days ago | IN | 0 ETH | 0.00000026 | ||||
| Force New Epoch | 8652198 | 61 days ago | IN | 0 ETH | 0.00000026 | ||||
| Force New Epoch | 8392909 | 64 days ago | IN | 0 ETH | 0.00000026 | ||||
| Force New Epoch | 8117699 | 67 days ago | IN | 0 ETH | 0.00000031 | ||||
| Force New Epoch | 7854065 | 70 days ago | IN | 0 ETH | 0.00000034 |
Loading...
Loading
Contract Name:
GTokenOpenPnlFeed
Compiler Version
v0.8.23+commit.f704f362
Optimization Enabled:
Yes with 750 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT
pragma solidity 0.8.23;
import {ChainlinkClient, Chainlink} from "@chainlink/contracts/src/v0.8/ChainlinkClient.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "../interfaces/IGToken.sol";
import "../interfaces/IOwnable.sol";
import "../interfaces/IGTokenOpenPnlFeed.sol";
/**
* @dev Manages open pnl oracle requests for a gToken vault
*/
contract GTokenOpenPnlFeed is ChainlinkClient, IGTokenOpenPnlFeed {
using Chainlink for Chainlink.Request;
// Constants
uint256 public immutable LINK_FEE_BALANCE_DIVIDER;
uint256 constant MIN_ANSWERS = 2;
uint256 constant MIN_REQUESTS_START = 1 hours;
uint256 constant MAX_REQUESTS_START = 1 weeks;
uint256 constant MIN_REQUESTS_EVERY = 1 hours;
uint256 constant MAX_REQUESTS_EVERY = 1 days;
uint256 constant MIN_REQUESTS_COUNT = 3;
uint256 constant MAX_REQUESTS_COUNT = 10;
// Params
IGToken public immutable gToken;
uint256 public requestsStart = 2 days;
uint256 public requestsEvery = 6 hours;
uint256 public requestsCount = 4;
address[] public oracles;
bytes32 public job;
uint256 public minAnswers;
// State
int256[] public nextEpochValues;
uint256 public nextEpochValuesRequestCount;
uint256 public nextEpochValuesLastRequest;
uint256 public lastRequestId;
mapping(bytes32 => uint256) public requestIds; // chainlink request id => requestId
mapping(uint256 => Request) public requests; // requestId => request
mapping(uint256 => int256[]) public requestAnswers; // requestId => open pnl (1e18)
constructor(
uint256 _LINK_FEE_BALANCE_DIVIDER,
address _linkToken,
IGToken _gToken,
address[] memory _oracles,
bytes32 _job,
uint256 _minAnswers
) {
require(
_LINK_FEE_BALANCE_DIVIDER > 0 &&
_linkToken != address(0) &&
address(_gToken) != address(0) &&
_oracles.length > 0 &&
_job != bytes32(0) &&
_minAnswers >= MIN_ANSWERS &&
_minAnswers <= _oracles.length,
"WRONG_PARAMS"
);
LINK_FEE_BALANCE_DIVIDER = _LINK_FEE_BALANCE_DIVIDER;
setChainlinkToken(_linkToken);
gToken = _gToken;
oracles = _oracles;
job = _job;
minAnswers = _minAnswers;
}
// Modifiers
modifier onlyGTokenOwner() {
// 2-week timelock
require(msg.sender == IOwnable(address(gToken)).owner(), "ONLY_OWNER");
_;
}
modifier onlyGTokenManager() {
// 3-day timelock
require(msg.sender == gToken.manager(), "ONLY_MANAGER");
_;
}
modifier onlyGTokenAdmin() {
// bypasses timelock, emergency functions only
require(msg.sender == gToken.admin(), "ONLY_ADMIN");
_;
}
// Manage parameters
function updateRequestsStart(uint256 newValue) public onlyGTokenOwner {
require(newValue >= MIN_REQUESTS_START, "BELOW_MIN");
require(newValue <= MAX_REQUESTS_START, "ABOVE_MAX");
requestsStart = newValue;
emit NumberParamUpdated("requestsStart", newValue);
}
function updateRequestsEvery(uint256 newValue) public onlyGTokenOwner {
require(newValue >= MIN_REQUESTS_EVERY, "BELOW_MIN");
require(newValue <= MAX_REQUESTS_EVERY, "ABOVE_MAX");
requestsEvery = newValue;
emit NumberParamUpdated("requestsEvery", newValue);
}
function updateRequestsCount(uint256 newValue) public onlyGTokenOwner {
require(newValue >= MIN_REQUESTS_COUNT, "BELOW_MIN");
require(newValue <= MAX_REQUESTS_COUNT, "ABOVE_MAX");
requestsCount = newValue;
emit NumberParamUpdated("requestsCount", newValue);
}
function updateRequestsInfoBatch(
uint256 newRequestsStart,
uint256 newRequestsEvery,
uint256 newRequestsCount
) external onlyGTokenOwner {
updateRequestsStart(newRequestsStart);
updateRequestsEvery(newRequestsEvery);
updateRequestsCount(newRequestsCount);
}
function updateMinAnswers(uint256 newValue) external onlyGTokenManager {
require(newValue >= MIN_ANSWERS, "BELOW_MIN");
require(newValue <= oracles.length / 2, "ABOVE_MAX");
minAnswers = newValue;
emit NumberParamUpdated("minAnswers", newValue);
}
function updateOracle(uint256 _index, address newValue) external onlyGTokenOwner {
require(_index < oracles.length, "INDEX_TOO_BIG");
require(newValue != address(0), "VALUE_0");
oracles[_index] = newValue;
emit OracleUpdated(_index, newValue);
}
function updateOracles(address[] memory newValues) external onlyGTokenOwner {
require(newValues.length >= minAnswers * 2, "ARRAY_TOO_SMALL");
oracles = newValues;
emit OraclesUpdated(newValues);
}
function updateJob(bytes32 newValue) external onlyGTokenManager {
require(newValue != bytes32(0), "VALUE_0");
job = newValue;
emit JobUpdated(newValue);
}
// Emergency function in case of oracle manipulation
function resetNextEpochValueRequests() external onlyGTokenAdmin {
uint256 reqToResetCount = nextEpochValuesRequestCount;
require(reqToResetCount > 0, "NO_REQUEST_TO_RESET");
delete nextEpochValues;
nextEpochValuesRequestCount = 0;
nextEpochValuesLastRequest = 0;
for (uint256 i; i < reqToResetCount; ++i) {
requests[lastRequestId - i].active = false;
}
emit NextEpochValuesReset(gToken.currentEpoch(), reqToResetCount);
}
// Safety function that anyone can call in case the function above is used in an abusive manner,
// which could theoretically delay withdrawals indefinitely since it prevents new epochs
function forceNewEpoch() external {
require(
block.timestamp - gToken.currentEpochStart() >= requestsStart + requestsEvery * requestsCount,
"TOO_EARLY"
);
uint256 newEpoch = startNewEpoch();
emit NewEpochForced(newEpoch);
}
// Called by gToken contract
function newOpenPnlRequestOrEpoch() external {
bool firstRequest = nextEpochValuesLastRequest == 0;
if (firstRequest && block.timestamp - gToken.currentEpochStart() >= requestsStart) {
makeOpenPnlRequest();
} else if (!firstRequest && block.timestamp - nextEpochValuesLastRequest >= requestsEvery) {
if (nextEpochValuesRequestCount < requestsCount) {
makeOpenPnlRequest();
} else if (nextEpochValues.length >= requestsCount) {
startNewEpoch();
}
}
}
// Create requests
function makeOpenPnlRequest() private {
Chainlink.Request memory linkRequest = buildChainlinkRequest(job, address(this), this.fulfill.selector);
uint256 linkFeePerNode = IERC20(chainlinkTokenAddress()).balanceOf(address(this)) /
LINK_FEE_BALANCE_DIVIDER /
oracles.length;
requests[++lastRequestId] = Request({initiated: true, active: true, linkFeePerNode: linkFeePerNode});
nextEpochValuesRequestCount++;
nextEpochValuesLastRequest = block.timestamp;
for (uint256 i; i < oracles.length; ++i) {
requestIds[sendChainlinkRequestTo(oracles[i], linkRequest, linkFeePerNode)] = lastRequestId;
}
emit NextEpochValueRequested(gToken.currentEpoch(), lastRequestId, job, oracles.length, linkFeePerNode);
}
// Handle answers
function fulfill(
bytes32 requestId,
int256 value // 1e18
) external recordChainlinkFulfillment(requestId) {
uint256 reqId = requestIds[requestId];
delete requestIds[requestId];
Request memory r = requests[reqId];
uint256 currentEpoch = gToken.currentEpoch();
emit RequestValueReceived(!r.active, currentEpoch, reqId, requestId, msg.sender, value, r.linkFeePerNode);
if (!r.active) {
return;
}
int256[] storage answers = requestAnswers[reqId];
answers.push(value);
if (answers.length == minAnswers) {
int256 medianValue = median(answers);
nextEpochValues.push(medianValue);
emit RequestMedianValueSet(currentEpoch, reqId, answers, medianValue);
requests[reqId].active = false;
delete requestAnswers[reqId];
}
}
// Increment epoch and update feed value
function startNewEpoch() private returns (uint256 newEpoch) {
nextEpochValuesRequestCount = 0;
nextEpochValuesLastRequest = 0;
uint256 currentEpochPositiveOpenPnl = gToken.currentEpochPositiveOpenPnl();
// If all responses arrived, use mean, otherwise it means we forced a new epoch,
// so as a safety we use the last epoch value
int256 newEpochOpenPnl = nextEpochValues.length >= requestsCount
? average(nextEpochValues)
: int256(currentEpochPositiveOpenPnl);
uint256 finalNewEpochPositiveOpenPnl = gToken.updateAccPnlPerTokenUsed(
currentEpochPositiveOpenPnl,
newEpochOpenPnl > 0 ? uint256(newEpochOpenPnl) : 0
);
newEpoch = gToken.currentEpoch();
emit NewEpoch(newEpoch, lastRequestId, nextEpochValues, newEpochOpenPnl, finalNewEpochPositiveOpenPnl);
delete nextEpochValues;
}
// Median function
function _swap(int256[] memory array, uint256 i, uint256 j) private pure {
(array[i], array[j]) = (array[j], array[i]);
}
function _sort(int256[] memory array, uint256 begin, uint256 end) private pure {
if (begin >= end) {
return;
}
uint256 j = begin;
int256 pivot = array[j];
for (uint256 i = begin + 1; i < end; ++i) {
if (array[i] < pivot) {
_swap(array, i, ++j);
}
}
_swap(array, begin, j);
_sort(array, begin, j);
_sort(array, j + 1, end);
}
function median(int256[] memory array) private pure returns (int256) {
_sort(array, 0, array.length);
return
array.length % 2 == 0
? (array[array.length / 2 - 1] + array[array.length / 2]) / 2
: array[array.length / 2];
}
// Average function
function average(int256[] memory array) private pure returns (int256) {
int256 sum;
for (uint256 i; i < array.length; ++i) {
sum += array[i];
}
return sum / int256(array.length);
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import {CBORChainlink} from "./vendor/CBORChainlink.sol";
import {BufferChainlink} from "./vendor/BufferChainlink.sol";
/**
* @title Library for common Chainlink functions
* @dev Uses imported CBOR library for encoding to buffer
*/
library Chainlink {
uint256 internal constant defaultBufferSize = 256; // solhint-disable-line const-name-snakecase
using CBORChainlink for BufferChainlink.buffer;
struct Request {
bytes32 id;
address callbackAddress;
bytes4 callbackFunctionId;
uint256 nonce;
BufferChainlink.buffer buf;
}
/**
* @notice Initializes a Chainlink request
* @dev Sets the ID, callback address, and callback function signature on the request
* @param self The uninitialized request
* @param jobId The Job Specification ID
* @param callbackAddr The callback address
* @param callbackFunc The callback function signature
* @return The initialized request
*/
function initialize(
Request memory self,
bytes32 jobId,
address callbackAddr,
bytes4 callbackFunc
) internal pure returns (Chainlink.Request memory) {
BufferChainlink.init(self.buf, defaultBufferSize);
self.id = jobId;
self.callbackAddress = callbackAddr;
self.callbackFunctionId = callbackFunc;
return self;
}
/**
* @notice Sets the data for the buffer without encoding CBOR on-chain
* @dev CBOR can be closed with curly-brackets {} or they can be left off
* @param self The initialized request
* @param data The CBOR data
*/
function setBuffer(Request memory self, bytes memory data) internal pure {
BufferChainlink.init(self.buf, data.length);
BufferChainlink.append(self.buf, data);
}
/**
* @notice Adds a string value to the request with a given key name
* @param self The initialized request
* @param key The name of the key
* @param value The string value to add
*/
function add(
Request memory self,
string memory key,
string memory value
) internal pure {
self.buf.encodeString(key);
self.buf.encodeString(value);
}
/**
* @notice Adds a bytes value to the request with a given key name
* @param self The initialized request
* @param key The name of the key
* @param value The bytes value to add
*/
function addBytes(
Request memory self,
string memory key,
bytes memory value
) internal pure {
self.buf.encodeString(key);
self.buf.encodeBytes(value);
}
/**
* @notice Adds a int256 value to the request with a given key name
* @param self The initialized request
* @param key The name of the key
* @param value The int256 value to add
*/
function addInt(
Request memory self,
string memory key,
int256 value
) internal pure {
self.buf.encodeString(key);
self.buf.encodeInt(value);
}
/**
* @notice Adds a uint256 value to the request with a given key name
* @param self The initialized request
* @param key The name of the key
* @param value The uint256 value to add
*/
function addUint(
Request memory self,
string memory key,
uint256 value
) internal pure {
self.buf.encodeString(key);
self.buf.encodeUInt(value);
}
/**
* @notice Adds an array of strings to the request with a given key name
* @param self The initialized request
* @param key The name of the key
* @param values The array of string values to add
*/
function addStringArray(
Request memory self,
string memory key,
string[] memory values
) internal pure {
self.buf.encodeString(key);
self.buf.startArray();
for (uint256 i = 0; i < values.length; i++) {
self.buf.encodeString(values[i]);
}
self.buf.endSequence();
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "./Chainlink.sol";
import "./interfaces/ENSInterface.sol";
import "./interfaces/LinkTokenInterface.sol";
import "./interfaces/ChainlinkRequestInterface.sol";
import "./interfaces/OperatorInterface.sol";
import "./interfaces/PointerInterface.sol";
import {ENSResolver as ENSResolver_Chainlink} from "./vendor/ENSResolver.sol";
/**
* @title The ChainlinkClient contract
* @notice Contract writers can inherit this contract in order to create requests for the
* Chainlink network
*/
abstract contract ChainlinkClient {
using Chainlink for Chainlink.Request;
uint256 internal constant LINK_DIVISIBILITY = 10**18;
uint256 private constant AMOUNT_OVERRIDE = 0;
address private constant SENDER_OVERRIDE = address(0);
uint256 private constant ORACLE_ARGS_VERSION = 1;
uint256 private constant OPERATOR_ARGS_VERSION = 2;
bytes32 private constant ENS_TOKEN_SUBNAME = keccak256("link");
bytes32 private constant ENS_ORACLE_SUBNAME = keccak256("oracle");
address private constant LINK_TOKEN_POINTER = 0xC89bD4E1632D3A43CB03AAAd5262cbe4038Bc571;
ENSInterface private s_ens;
bytes32 private s_ensNode;
LinkTokenInterface private s_link;
OperatorInterface private s_oracle;
uint256 private s_requestCount = 1;
mapping(bytes32 => address) private s_pendingRequests;
event ChainlinkRequested(bytes32 indexed id);
event ChainlinkFulfilled(bytes32 indexed id);
event ChainlinkCancelled(bytes32 indexed id);
/**
* @notice Creates a request that can hold additional parameters
* @param specId The Job Specification ID that the request will be created for
* @param callbackAddr address to operate the callback on
* @param callbackFunctionSignature function signature to use for the callback
* @return A Chainlink Request struct in memory
*/
function buildChainlinkRequest(
bytes32 specId,
address callbackAddr,
bytes4 callbackFunctionSignature
) internal pure returns (Chainlink.Request memory) {
Chainlink.Request memory req;
return req.initialize(specId, callbackAddr, callbackFunctionSignature);
}
/**
* @notice Creates a request that can hold additional parameters
* @param specId The Job Specification ID that the request will be created for
* @param callbackFunctionSignature function signature to use for the callback
* @return A Chainlink Request struct in memory
*/
function buildOperatorRequest(bytes32 specId, bytes4 callbackFunctionSignature)
internal
view
returns (Chainlink.Request memory)
{
Chainlink.Request memory req;
return req.initialize(specId, address(this), callbackFunctionSignature);
}
/**
* @notice Creates a Chainlink request to the stored oracle address
* @dev Calls `chainlinkRequestTo` with the stored oracle address
* @param req The initialized Chainlink Request
* @param payment The amount of LINK to send for the request
* @return requestId The request ID
*/
function sendChainlinkRequest(Chainlink.Request memory req, uint256 payment) internal returns (bytes32) {
return sendChainlinkRequestTo(address(s_oracle), req, payment);
}
/**
* @notice Creates a Chainlink request to the specified oracle address
* @dev Generates and stores a request ID, increments the local nonce, and uses `transferAndCall` to
* send LINK which creates a request on the target oracle contract.
* Emits ChainlinkRequested event.
* @param oracleAddress The address of the oracle for the request
* @param req The initialized Chainlink Request
* @param payment The amount of LINK to send for the request
* @return requestId The request ID
*/
function sendChainlinkRequestTo(
address oracleAddress,
Chainlink.Request memory req,
uint256 payment
) internal returns (bytes32 requestId) {
uint256 nonce = s_requestCount;
s_requestCount = nonce + 1;
bytes memory encodedRequest = abi.encodeWithSelector(
ChainlinkRequestInterface.oracleRequest.selector,
SENDER_OVERRIDE, // Sender value - overridden by onTokenTransfer by the requesting contract's address
AMOUNT_OVERRIDE, // Amount value - overridden by onTokenTransfer by the actual amount of LINK sent
req.id,
address(this),
req.callbackFunctionId,
nonce,
ORACLE_ARGS_VERSION,
req.buf.buf
);
return _rawRequest(oracleAddress, nonce, payment, encodedRequest);
}
/**
* @notice Creates a Chainlink request to the stored oracle address
* @dev This function supports multi-word response
* @dev Calls `sendOperatorRequestTo` with the stored oracle address
* @param req The initialized Chainlink Request
* @param payment The amount of LINK to send for the request
* @return requestId The request ID
*/
function sendOperatorRequest(Chainlink.Request memory req, uint256 payment) internal returns (bytes32) {
return sendOperatorRequestTo(address(s_oracle), req, payment);
}
/**
* @notice Creates a Chainlink request to the specified oracle address
* @dev This function supports multi-word response
* @dev Generates and stores a request ID, increments the local nonce, and uses `transferAndCall` to
* send LINK which creates a request on the target oracle contract.
* Emits ChainlinkRequested event.
* @param oracleAddress The address of the oracle for the request
* @param req The initialized Chainlink Request
* @param payment The amount of LINK to send for the request
* @return requestId The request ID
*/
function sendOperatorRequestTo(
address oracleAddress,
Chainlink.Request memory req,
uint256 payment
) internal returns (bytes32 requestId) {
uint256 nonce = s_requestCount;
s_requestCount = nonce + 1;
bytes memory encodedRequest = abi.encodeWithSelector(
OperatorInterface.operatorRequest.selector,
SENDER_OVERRIDE, // Sender value - overridden by onTokenTransfer by the requesting contract's address
AMOUNT_OVERRIDE, // Amount value - overridden by onTokenTransfer by the actual amount of LINK sent
req.id,
req.callbackFunctionId,
nonce,
OPERATOR_ARGS_VERSION,
req.buf.buf
);
return _rawRequest(oracleAddress, nonce, payment, encodedRequest);
}
/**
* @notice Make a request to an oracle
* @param oracleAddress The address of the oracle for the request
* @param nonce used to generate the request ID
* @param payment The amount of LINK to send for the request
* @param encodedRequest data encoded for request type specific format
* @return requestId The request ID
*/
function _rawRequest(
address oracleAddress,
uint256 nonce,
uint256 payment,
bytes memory encodedRequest
) private returns (bytes32 requestId) {
requestId = keccak256(abi.encodePacked(this, nonce));
s_pendingRequests[requestId] = oracleAddress;
emit ChainlinkRequested(requestId);
require(s_link.transferAndCall(oracleAddress, payment, encodedRequest), "unable to transferAndCall to oracle");
}
/**
* @notice Allows a request to be cancelled if it has not been fulfilled
* @dev Requires keeping track of the expiration value emitted from the oracle contract.
* Deletes the request from the `pendingRequests` mapping.
* Emits ChainlinkCancelled event.
* @param requestId The request ID
* @param payment The amount of LINK sent for the request
* @param callbackFunc The callback function specified for the request
* @param expiration The time of the expiration for the request
*/
function cancelChainlinkRequest(
bytes32 requestId,
uint256 payment,
bytes4 callbackFunc,
uint256 expiration
) internal {
OperatorInterface requested = OperatorInterface(s_pendingRequests[requestId]);
delete s_pendingRequests[requestId];
emit ChainlinkCancelled(requestId);
requested.cancelOracleRequest(requestId, payment, callbackFunc, expiration);
}
/**
* @notice the next request count to be used in generating a nonce
* @dev starts at 1 in order to ensure consistent gas cost
* @return returns the next request count to be used in a nonce
*/
function getNextRequestCount() internal view returns (uint256) {
return s_requestCount;
}
/**
* @notice Sets the stored oracle address
* @param oracleAddress The address of the oracle contract
*/
function setChainlinkOracle(address oracleAddress) internal {
s_oracle = OperatorInterface(oracleAddress);
}
/**
* @notice Sets the LINK token address
* @param linkAddress The address of the LINK token contract
*/
function setChainlinkToken(address linkAddress) internal {
s_link = LinkTokenInterface(linkAddress);
}
/**
* @notice Sets the Chainlink token address for the public
* network as given by the Pointer contract
*/
function setPublicChainlinkToken() internal {
setChainlinkToken(PointerInterface(LINK_TOKEN_POINTER).getAddress());
}
/**
* @notice Retrieves the stored address of the LINK token
* @return The address of the LINK token
*/
function chainlinkTokenAddress() internal view returns (address) {
return address(s_link);
}
/**
* @notice Retrieves the stored address of the oracle contract
* @return The address of the oracle contract
*/
function chainlinkOracleAddress() internal view returns (address) {
return address(s_oracle);
}
/**
* @notice Allows for a request which was created on another contract to be fulfilled
* on this contract
* @param oracleAddress The address of the oracle contract that will fulfill the request
* @param requestId The request ID used for the response
*/
function addChainlinkExternalRequest(address oracleAddress, bytes32 requestId) internal notPendingRequest(requestId) {
s_pendingRequests[requestId] = oracleAddress;
}
/**
* @notice Sets the stored oracle and LINK token contracts with the addresses resolved by ENS
* @dev Accounts for subnodes having different resolvers
* @param ensAddress The address of the ENS contract
* @param node The ENS node hash
*/
function useChainlinkWithENS(address ensAddress, bytes32 node) internal {
s_ens = ENSInterface(ensAddress);
s_ensNode = node;
bytes32 linkSubnode = keccak256(abi.encodePacked(s_ensNode, ENS_TOKEN_SUBNAME));
ENSResolver_Chainlink resolver = ENSResolver_Chainlink(s_ens.resolver(linkSubnode));
setChainlinkToken(resolver.addr(linkSubnode));
updateChainlinkOracleWithENS();
}
/**
* @notice Sets the stored oracle contract with the address resolved by ENS
* @dev This may be called on its own as long as `useChainlinkWithENS` has been called previously
*/
function updateChainlinkOracleWithENS() internal {
bytes32 oracleSubnode = keccak256(abi.encodePacked(s_ensNode, ENS_ORACLE_SUBNAME));
ENSResolver_Chainlink resolver = ENSResolver_Chainlink(s_ens.resolver(oracleSubnode));
setChainlinkOracle(resolver.addr(oracleSubnode));
}
/**
* @notice Ensures that the fulfillment is valid for this contract
* @dev Use if the contract developer prefers methods instead of modifiers for validation
* @param requestId The request ID for fulfillment
*/
function validateChainlinkCallback(bytes32 requestId)
internal
recordChainlinkFulfillment(requestId)
// solhint-disable-next-line no-empty-blocks
{
}
/**
* @dev Reverts if the sender is not the oracle of the request.
* Emits ChainlinkFulfilled event.
* @param requestId The request ID for fulfillment
*/
modifier recordChainlinkFulfillment(bytes32 requestId) {
require(msg.sender == s_pendingRequests[requestId], "Source must be the oracle of the request");
delete s_pendingRequests[requestId];
emit ChainlinkFulfilled(requestId);
_;
}
/**
* @dev Reverts if the request is already pending
* @param requestId The request ID for fulfillment
*/
modifier notPendingRequest(bytes32 requestId) {
require(s_pendingRequests[requestId] == address(0), "Request is already pending");
_;
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
interface ChainlinkRequestInterface {
function oracleRequest(
address sender,
uint256 requestPrice,
bytes32 serviceAgreementID,
address callbackAddress,
bytes4 callbackFunctionId,
uint256 nonce,
uint256 dataVersion,
bytes calldata data
) external;
function cancelOracleRequest(
bytes32 requestId,
uint256 payment,
bytes4 callbackFunctionId,
uint256 expiration
) external;
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
interface ENSInterface {
// Logged when the owner of a node assigns a new owner to a subnode.
event NewOwner(bytes32 indexed node, bytes32 indexed label, address owner);
// Logged when the owner of a node transfers ownership to a new account.
event Transfer(bytes32 indexed node, address owner);
// Logged when the resolver for a node changes.
event NewResolver(bytes32 indexed node, address resolver);
// Logged when the TTL of a node changes
event NewTTL(bytes32 indexed node, uint64 ttl);
function setSubnodeOwner(
bytes32 node,
bytes32 label,
address owner
) external;
function setResolver(bytes32 node, address resolver) external;
function setOwner(bytes32 node, address owner) external;
function setTTL(bytes32 node, uint64 ttl) external;
function owner(bytes32 node) external view returns (address);
function resolver(bytes32 node) external view returns (address);
function ttl(bytes32 node) external view returns (uint64);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
interface LinkTokenInterface {
function allowance(address owner, address spender) external view returns (uint256 remaining);
function approve(address spender, uint256 value) external returns (bool success);
function balanceOf(address owner) external view returns (uint256 balance);
function decimals() external view returns (uint8 decimalPlaces);
function decreaseApproval(address spender, uint256 addedValue) external returns (bool success);
function increaseApproval(address spender, uint256 subtractedValue) external;
function name() external view returns (string memory tokenName);
function symbol() external view returns (string memory tokenSymbol);
function totalSupply() external view returns (uint256 totalTokensIssued);
function transfer(address to, uint256 value) external returns (bool success);
function transferAndCall(
address to,
uint256 value,
bytes calldata data
) external returns (bool success);
function transferFrom(
address from,
address to,
uint256 value
) external returns (bool success);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "./OracleInterface.sol";
import "./ChainlinkRequestInterface.sol";
interface OperatorInterface is OracleInterface, ChainlinkRequestInterface {
function operatorRequest(
address sender,
uint256 payment,
bytes32 specId,
bytes4 callbackFunctionId,
uint256 nonce,
uint256 dataVersion,
bytes calldata data
) external;
function fulfillOracleRequest2(
bytes32 requestId,
uint256 payment,
address callbackAddress,
bytes4 callbackFunctionId,
uint256 expiration,
bytes calldata data
) external returns (bool);
function ownerTransferAndCall(
address to,
uint256 value,
bytes calldata data
) external returns (bool success);
function distributeFunds(address payable[] calldata receivers, uint256[] calldata amounts) external payable;
function getAuthorizedSenders() external returns (address[] memory);
function setAuthorizedSenders(address[] calldata senders) external;
function getForwarder() external returns (address);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
interface OracleInterface {
function fulfillOracleRequest(
bytes32 requestId,
uint256 payment,
address callbackAddress,
bytes4 callbackFunctionId,
uint256 expiration,
bytes32 data
) external returns (bool);
function isAuthorizedSender(address node) external view returns (bool);
function withdraw(address recipient, uint256 amount) external;
function withdrawable() external view returns (uint256);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
interface PointerInterface {
function getAddress() external view returns (address);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/**
* @dev A library for working with mutable byte buffers in Solidity.
*
* Byte buffers are mutable and expandable, and provide a variety of primitives
* for writing to them. At any time you can fetch a bytes object containing the
* current contents of the buffer. The bytes object should not be stored between
* operations, as it may change due to resizing of the buffer.
*/
library BufferChainlink {
/**
* @dev Represents a mutable buffer. Buffers have a current value (buf) and
* a capacity. The capacity may be longer than the current value, in
* which case it can be extended without the need to allocate more memory.
*/
struct buffer {
bytes buf;
uint256 capacity;
}
/**
* @dev Initializes a buffer with an initial capacity.
* @param buf The buffer to initialize.
* @param capacity The number of bytes of space to allocate the buffer.
* @return The buffer, for chaining.
*/
function init(buffer memory buf, uint256 capacity) internal pure returns (buffer memory) {
if (capacity % 32 != 0) {
capacity += 32 - (capacity % 32);
}
// Allocate space for the buffer data
buf.capacity = capacity;
assembly {
let ptr := mload(0x40)
mstore(buf, ptr)
mstore(ptr, 0)
mstore(0x40, add(32, add(ptr, capacity)))
}
return buf;
}
/**
* @dev Initializes a new buffer from an existing bytes object.
* Changes to the buffer may mutate the original value.
* @param b The bytes object to initialize the buffer with.
* @return A new buffer.
*/
function fromBytes(bytes memory b) internal pure returns (buffer memory) {
buffer memory buf;
buf.buf = b;
buf.capacity = b.length;
return buf;
}
function resize(buffer memory buf, uint256 capacity) private pure {
bytes memory oldbuf = buf.buf;
init(buf, capacity);
append(buf, oldbuf);
}
function max(uint256 a, uint256 b) private pure returns (uint256) {
if (a > b) {
return a;
}
return b;
}
/**
* @dev Sets buffer length to 0.
* @param buf The buffer to truncate.
* @return The original buffer, for chaining..
*/
function truncate(buffer memory buf) internal pure returns (buffer memory) {
assembly {
let bufptr := mload(buf)
mstore(bufptr, 0)
}
return buf;
}
/**
* @dev Writes a byte string to a buffer. Resizes if doing so would exceed
* the capacity of the buffer.
* @param buf The buffer to append to.
* @param off The start offset to write to.
* @param data The data to append.
* @param len The number of bytes to copy.
* @return The original buffer, for chaining.
*/
function write(
buffer memory buf,
uint256 off,
bytes memory data,
uint256 len
) internal pure returns (buffer memory) {
require(len <= data.length);
if (off + len > buf.capacity) {
resize(buf, max(buf.capacity, len + off) * 2);
}
uint256 dest;
uint256 src;
assembly {
// Memory address of the buffer data
let bufptr := mload(buf)
// Length of existing buffer data
let buflen := mload(bufptr)
// Start address = buffer address + offset + sizeof(buffer length)
dest := add(add(bufptr, 32), off)
// Update buffer length if we're extending it
if gt(add(len, off), buflen) {
mstore(bufptr, add(len, off))
}
src := add(data, 32)
}
// Copy word-length chunks while possible
for (; len >= 32; len -= 32) {
assembly {
mstore(dest, mload(src))
}
dest += 32;
src += 32;
}
// Copy remaining bytes
unchecked {
uint256 mask = (256**(32 - len)) - 1;
assembly {
let srcpart := and(mload(src), not(mask))
let destpart := and(mload(dest), mask)
mstore(dest, or(destpart, srcpart))
}
}
return buf;
}
/**
* @dev Appends a byte string to a buffer. Resizes if doing so would exceed
* the capacity of the buffer.
* @param buf The buffer to append to.
* @param data The data to append.
* @param len The number of bytes to copy.
* @return The original buffer, for chaining.
*/
function append(
buffer memory buf,
bytes memory data,
uint256 len
) internal pure returns (buffer memory) {
return write(buf, buf.buf.length, data, len);
}
/**
* @dev Appends a byte string to a buffer. Resizes if doing so would exceed
* the capacity of the buffer.
* @param buf The buffer to append to.
* @param data The data to append.
* @return The original buffer, for chaining.
*/
function append(buffer memory buf, bytes memory data) internal pure returns (buffer memory) {
return write(buf, buf.buf.length, data, data.length);
}
/**
* @dev Writes a byte to the buffer. Resizes if doing so would exceed the
* capacity of the buffer.
* @param buf The buffer to append to.
* @param off The offset to write the byte at.
* @param data The data to append.
* @return The original buffer, for chaining.
*/
function writeUint8(
buffer memory buf,
uint256 off,
uint8 data
) internal pure returns (buffer memory) {
if (off >= buf.capacity) {
resize(buf, buf.capacity * 2);
}
assembly {
// Memory address of the buffer data
let bufptr := mload(buf)
// Length of existing buffer data
let buflen := mload(bufptr)
// Address = buffer address + sizeof(buffer length) + off
let dest := add(add(bufptr, off), 32)
mstore8(dest, data)
// Update buffer length if we extended it
if eq(off, buflen) {
mstore(bufptr, add(buflen, 1))
}
}
return buf;
}
/**
* @dev Appends a byte to the buffer. Resizes if doing so would exceed the
* capacity of the buffer.
* @param buf The buffer to append to.
* @param data The data to append.
* @return The original buffer, for chaining.
*/
function appendUint8(buffer memory buf, uint8 data) internal pure returns (buffer memory) {
return writeUint8(buf, buf.buf.length, data);
}
/**
* @dev Writes up to 32 bytes to the buffer. Resizes if doing so would
* exceed the capacity of the buffer.
* @param buf The buffer to append to.
* @param off The offset to write at.
* @param data The data to append.
* @param len The number of bytes to write (left-aligned).
* @return The original buffer, for chaining.
*/
function write(
buffer memory buf,
uint256 off,
bytes32 data,
uint256 len
) private pure returns (buffer memory) {
if (len + off > buf.capacity) {
resize(buf, (len + off) * 2);
}
unchecked {
uint256 mask = (256**len) - 1;
// Right-align data
data = data >> (8 * (32 - len));
assembly {
// Memory address of the buffer data
let bufptr := mload(buf)
// Address = buffer address + sizeof(buffer length) + off + len
let dest := add(add(bufptr, off), len)
mstore(dest, or(and(mload(dest), not(mask)), data))
// Update buffer length if we extended it
if gt(add(off, len), mload(bufptr)) {
mstore(bufptr, add(off, len))
}
}
}
return buf;
}
/**
* @dev Writes a bytes20 to the buffer. Resizes if doing so would exceed the
* capacity of the buffer.
* @param buf The buffer to append to.
* @param off The offset to write at.
* @param data The data to append.
* @return The original buffer, for chaining.
*/
function writeBytes20(
buffer memory buf,
uint256 off,
bytes20 data
) internal pure returns (buffer memory) {
return write(buf, off, bytes32(data), 20);
}
/**
* @dev Appends a bytes20 to the buffer. Resizes if doing so would exceed
* the capacity of the buffer.
* @param buf The buffer to append to.
* @param data The data to append.
* @return The original buffer, for chhaining.
*/
function appendBytes20(buffer memory buf, bytes20 data) internal pure returns (buffer memory) {
return write(buf, buf.buf.length, bytes32(data), 20);
}
/**
* @dev Appends a bytes32 to the buffer. Resizes if doing so would exceed
* the capacity of the buffer.
* @param buf The buffer to append to.
* @param data The data to append.
* @return The original buffer, for chaining.
*/
function appendBytes32(buffer memory buf, bytes32 data) internal pure returns (buffer memory) {
return write(buf, buf.buf.length, data, 32);
}
/**
* @dev Writes an integer to the buffer. Resizes if doing so would exceed
* the capacity of the buffer.
* @param buf The buffer to append to.
* @param off The offset to write at.
* @param data The data to append.
* @param len The number of bytes to write (right-aligned).
* @return The original buffer, for chaining.
*/
function writeInt(
buffer memory buf,
uint256 off,
uint256 data,
uint256 len
) private pure returns (buffer memory) {
if (len + off > buf.capacity) {
resize(buf, (len + off) * 2);
}
uint256 mask = (256**len) - 1;
assembly {
// Memory address of the buffer data
let bufptr := mload(buf)
// Address = buffer address + off + sizeof(buffer length) + len
let dest := add(add(bufptr, off), len)
mstore(dest, or(and(mload(dest), not(mask)), data))
// Update buffer length if we extended it
if gt(add(off, len), mload(bufptr)) {
mstore(bufptr, add(off, len))
}
}
return buf;
}
/**
* @dev Appends a byte to the end of the buffer. Resizes if doing so would
* exceed the capacity of the buffer.
* @param buf The buffer to append to.
* @param data The data to append.
* @return The original buffer.
*/
function appendInt(
buffer memory buf,
uint256 data,
uint256 len
) internal pure returns (buffer memory) {
return writeInt(buf, buf.buf.length, data, len);
}
}// SPDX-License-Identifier: MIT
pragma solidity >=0.4.19;
import {BufferChainlink} from "./BufferChainlink.sol";
library CBORChainlink {
using BufferChainlink for BufferChainlink.buffer;
uint8 private constant MAJOR_TYPE_INT = 0;
uint8 private constant MAJOR_TYPE_NEGATIVE_INT = 1;
uint8 private constant MAJOR_TYPE_BYTES = 2;
uint8 private constant MAJOR_TYPE_STRING = 3;
uint8 private constant MAJOR_TYPE_ARRAY = 4;
uint8 private constant MAJOR_TYPE_MAP = 5;
uint8 private constant MAJOR_TYPE_TAG = 6;
uint8 private constant MAJOR_TYPE_CONTENT_FREE = 7;
uint8 private constant TAG_TYPE_BIGNUM = 2;
uint8 private constant TAG_TYPE_NEGATIVE_BIGNUM = 3;
function encodeFixedNumeric(BufferChainlink.buffer memory buf, uint8 major, uint64 value) private pure {
if(value <= 23) {
buf.appendUint8(uint8((major << 5) | value));
} else if (value <= 0xFF) {
buf.appendUint8(uint8((major << 5) | 24));
buf.appendInt(value, 1);
} else if (value <= 0xFFFF) {
buf.appendUint8(uint8((major << 5) | 25));
buf.appendInt(value, 2);
} else if (value <= 0xFFFFFFFF) {
buf.appendUint8(uint8((major << 5) | 26));
buf.appendInt(value, 4);
} else {
buf.appendUint8(uint8((major << 5) | 27));
buf.appendInt(value, 8);
}
}
function encodeIndefiniteLengthType(BufferChainlink.buffer memory buf, uint8 major) private pure {
buf.appendUint8(uint8((major << 5) | 31));
}
function encodeUInt(BufferChainlink.buffer memory buf, uint value) internal pure {
if(value > 0xFFFFFFFFFFFFFFFF) {
encodeBigNum(buf, value);
} else {
encodeFixedNumeric(buf, MAJOR_TYPE_INT, uint64(value));
}
}
function encodeInt(BufferChainlink.buffer memory buf, int value) internal pure {
if(value < -0x10000000000000000) {
encodeSignedBigNum(buf, value);
} else if(value > 0xFFFFFFFFFFFFFFFF) {
encodeBigNum(buf, uint(value));
} else if(value >= 0) {
encodeFixedNumeric(buf, MAJOR_TYPE_INT, uint64(uint256(value)));
} else {
encodeFixedNumeric(buf, MAJOR_TYPE_NEGATIVE_INT, uint64(uint256(-1 - value)));
}
}
function encodeBytes(BufferChainlink.buffer memory buf, bytes memory value) internal pure {
encodeFixedNumeric(buf, MAJOR_TYPE_BYTES, uint64(value.length));
buf.append(value);
}
function encodeBigNum(BufferChainlink.buffer memory buf, uint value) internal pure {
buf.appendUint8(uint8((MAJOR_TYPE_TAG << 5) | TAG_TYPE_BIGNUM));
encodeBytes(buf, abi.encode(value));
}
function encodeSignedBigNum(BufferChainlink.buffer memory buf, int input) internal pure {
buf.appendUint8(uint8((MAJOR_TYPE_TAG << 5) | TAG_TYPE_NEGATIVE_BIGNUM));
encodeBytes(buf, abi.encode(uint256(-1 - input)));
}
function encodeString(BufferChainlink.buffer memory buf, string memory value) internal pure {
encodeFixedNumeric(buf, MAJOR_TYPE_STRING, uint64(bytes(value).length));
buf.append(bytes(value));
}
function startArray(BufferChainlink.buffer memory buf) internal pure {
encodeIndefiniteLengthType(buf, MAJOR_TYPE_ARRAY);
}
function startMap(BufferChainlink.buffer memory buf) internal pure {
encodeIndefiniteLengthType(buf, MAJOR_TYPE_MAP);
}
function endSequence(BufferChainlink.buffer memory buf) internal pure {
encodeIndefiniteLengthType(buf, MAJOR_TYPE_CONTENT_FREE);
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
abstract contract ENSResolver {
function addr(bytes32 node) public view virtual returns (address);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
/**
* @dev Returns the amount of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the amount of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves `amount` tokens from the caller's account to `to`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address to, uint256 amount) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 amount) external returns (bool);
/**
* @dev Moves `amount` tokens from `from` to `to` using the
* allowance mechanism. `amount` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(address from, address to, uint256 amount) external returns (bool);
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.23;
/**
* @dev Interface for GToken contract
*/
interface IGToken {
struct GnsPriceProvider {
address addr;
bytes signature;
}
struct LockedDeposit {
address owner;
uint256 shares; // collateralConfig.precision
uint256 assetsDeposited; // collateralConfig.precision
uint256 assetsDiscount; // collateralConfig.precision
uint256 atTimestamp; // timestamp
uint256 lockDuration; // timestamp
}
struct ContractAddresses {
address asset;
address owner; // 2-week timelock contract
address manager; // 3-day timelock contract
address admin; // bypasses timelock, access to emergency functions
address gnsToken;
address lockedDepositNft;
address pnlHandler;
address openTradesPnlFeed;
GnsPriceProvider gnsPriceProvider;
}
struct Meta {
string name;
string symbol;
}
function manager() external view returns (address);
function admin() external view returns (address);
function currentEpoch() external view returns (uint256);
function currentEpochStart() external view returns (uint256);
function currentEpochPositiveOpenPnl() external view returns (uint256);
function updateAccPnlPerTokenUsed(
uint256 prevPositiveOpenPnl,
uint256 newPositiveOpenPnl
) external returns (uint256);
function getLockedDeposit(uint256 depositId) external view returns (LockedDeposit memory);
function sendAssets(uint256 assets, address receiver) external;
function receiveAssets(uint256 assets, address user, bool _burn) external;
function distributeReward(uint256 assets) external;
function tvl() external view returns (uint256);
function marketCap() external view returns (uint256);
function shareToAssetsPrice() external view returns (uint256);
function collateralConfig() external view returns (uint128, uint128);
event ManagerUpdated(address newValue);
event AdminUpdated(address newValue);
event PnlHandlerUpdated(address newValue);
event OpenTradesPnlFeedUpdated(address newValue);
event GnsPriceProviderUpdated(GnsPriceProvider newValue);
event WithdrawLockThresholdsPUpdated(uint256[2] newValue);
event MaxAccOpenPnlDeltaUpdated(uint256 newValue);
event MaxDailyAccPnlDeltaUpdated(uint256 newValue);
event MaxSupplyIncreaseDailyPUpdated(uint256 newValue);
event LossesBurnPUpdated(uint256 newValue);
event MaxGnsSupplyMintDailyPUpdated(uint256 newValue);
event MaxDiscountPUpdated(uint256 newValue);
event MaxDiscountThresholdPUpdated(uint256 newValue);
event CurrentMaxSupplyUpdated(uint256 newValue);
event DailyAccPnlDeltaReset();
event ShareToAssetsPriceUpdated(uint256 newValue);
event OpenTradesPnlFeedCallFailed();
event WithdrawRequested(
address indexed sender,
address indexed owner,
uint256 shares,
uint256 currEpoch,
uint256 indexed unlockEpoch
);
event WithdrawCanceled(
address indexed sender,
address indexed owner,
uint256 shares,
uint256 currEpoch,
uint256 indexed unlockEpoch
);
event DepositLocked(address indexed sender, address indexed owner, uint256 depositId, LockedDeposit d);
event DepositUnlocked(
address indexed sender,
address indexed receiver,
address indexed owner,
uint256 depositId,
LockedDeposit d
);
event RewardDistributed(address indexed sender, uint256 assets);
event AssetsSent(address indexed sender, address indexed receiver, uint256 assets);
event AssetsReceived(address indexed sender, address indexed user, uint256 assets, uint256 assetsLessDeplete, bool burn);
event Depleted(address indexed sender, uint256 assets, uint256 amountGns);
event Refilled(address indexed sender, uint256 assets, uint256 amountGns);
event AccPnlPerTokenUsedUpdated(
address indexed sender,
uint256 indexed newEpoch,
uint256 prevPositiveOpenPnl,
uint256 newPositiveOpenPnl,
uint256 newEpochPositiveOpenPnl,
int256 newAccPnlPerTokenUsed
);
error OnlyManager();
error OnlyTradingPnlHandler();
error OnlyPnlFeed();
error AddressZero();
error PriceZero();
error ValueZero();
error BytesZero();
error NoActiveDiscount();
error BelowMin();
error AboveMax();
error WrongValue();
error WrongValues();
error GnsPriceCallFailed();
error GnsTokenPriceZero();
error PendingWithdrawal();
error EndOfEpoch();
error NotAllowed();
error NoDiscount();
error NotUnlocked();
error NotEnoughAssets();
error MaxDailyPnl();
error NotUnderCollateralized();
error AboveInflationLimit();
// Ownable
error OwnableInvalidOwner(address owner);
// ERC4626
error ERC4626ExceededMaxDeposit();
error ERC4626ExceededMaxMint();
error ERC4626ExceededMaxWithdraw();
error ERC4626ExceededMaxRedeem();
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.23;
/**
* @dev Interface for GTokenOpenPnlFeed contract
*/
interface IGTokenOpenPnlFeed {
struct Request {
bool initiated;
bool active;
uint256 linkFeePerNode;
}
function nextEpochValuesRequestCount() external view returns (uint256);
function newOpenPnlRequestOrEpoch() external;
function fulfill(bytes32 requestId, int256 value) external;
event NumberParamUpdated(string name, uint256 newValue);
event OracleUpdated(uint256 index, address newValue);
event OraclesUpdated(address[] newValues);
event JobUpdated(bytes32 newValue);
event NextEpochValuesReset(uint256 indexed currEpoch, uint256 requestsResetCount);
event NewEpochForced(uint256 indexed newEpoch);
event NextEpochValueRequested(
uint256 indexed currEpoch,
uint256 indexed requestId,
bytes32 job,
uint256 oraclesCount,
uint256 linkFeePerNode
);
event NewEpoch(
uint256 indexed newEpoch,
uint256 indexed requestId,
int256[] epochMedianValues,
int256 epochAverageValue,
uint256 newEpochPositiveOpenPnl
);
event RequestValueReceived(
bool isLate,
uint256 indexed currEpoch,
uint256 indexed requestId,
bytes32 oracleRequestId,
address indexed oracle,
int256 requestValue,
uint256 linkFee
);
event RequestMedianValueSet(
uint256 indexed currEpoch,
uint256 indexed requestId,
int256[] requestValues,
int256 medianValue
);
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.23;
/**
* @dev Interface for ownable contracts
*/
interface IOwnable {
function owner() external view returns (address);
}{
"optimizer": {
"enabled": true,
"runs": 750
},
"evmVersion": "paris",
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"uint256","name":"_LINK_FEE_BALANCE_DIVIDER","type":"uint256"},{"internalType":"address","name":"_linkToken","type":"address"},{"internalType":"contract IGToken","name":"_gToken","type":"address"},{"internalType":"address[]","name":"_oracles","type":"address[]"},{"internalType":"bytes32","name":"_job","type":"bytes32"},{"internalType":"uint256","name":"_minAnswers","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"id","type":"bytes32"}],"name":"ChainlinkCancelled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"id","type":"bytes32"}],"name":"ChainlinkFulfilled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"id","type":"bytes32"}],"name":"ChainlinkRequested","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"newValue","type":"bytes32"}],"name":"JobUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"newEpoch","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"requestId","type":"uint256"},{"indexed":false,"internalType":"int256[]","name":"epochMedianValues","type":"int256[]"},{"indexed":false,"internalType":"int256","name":"epochAverageValue","type":"int256"},{"indexed":false,"internalType":"uint256","name":"newEpochPositiveOpenPnl","type":"uint256"}],"name":"NewEpoch","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"newEpoch","type":"uint256"}],"name":"NewEpochForced","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"currEpoch","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"requestId","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"job","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"oraclesCount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"linkFeePerNode","type":"uint256"}],"name":"NextEpochValueRequested","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"currEpoch","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"requestsResetCount","type":"uint256"}],"name":"NextEpochValuesReset","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"name","type":"string"},{"indexed":false,"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"NumberParamUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"index","type":"uint256"},{"indexed":false,"internalType":"address","name":"newValue","type":"address"}],"name":"OracleUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address[]","name":"newValues","type":"address[]"}],"name":"OraclesUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"currEpoch","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"requestId","type":"uint256"},{"indexed":false,"internalType":"int256[]","name":"requestValues","type":"int256[]"},{"indexed":false,"internalType":"int256","name":"medianValue","type":"int256"}],"name":"RequestMedianValueSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"isLate","type":"bool"},{"indexed":true,"internalType":"uint256","name":"currEpoch","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"requestId","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"oracleRequestId","type":"bytes32"},{"indexed":true,"internalType":"address","name":"oracle","type":"address"},{"indexed":false,"internalType":"int256","name":"requestValue","type":"int256"},{"indexed":false,"internalType":"uint256","name":"linkFee","type":"uint256"}],"name":"RequestValueReceived","type":"event"},{"inputs":[],"name":"LINK_FEE_BALANCE_DIVIDER","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"forceNewEpoch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"requestId","type":"bytes32"},{"internalType":"int256","name":"value","type":"int256"}],"name":"fulfill","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"gToken","outputs":[{"internalType":"contract IGToken","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"job","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastRequestId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minAnswers","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"newOpenPnlRequestOrEpoch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"nextEpochValues","outputs":[{"internalType":"int256","name":"","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nextEpochValuesLastRequest","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nextEpochValuesRequestCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"oracles","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"requestAnswers","outputs":[{"internalType":"int256","name":"","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"requestIds","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"requests","outputs":[{"internalType":"bool","name":"initiated","type":"bool"},{"internalType":"bool","name":"active","type":"bool"},{"internalType":"uint256","name":"linkFeePerNode","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"requestsCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"requestsEvery","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"requestsStart","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"resetNextEpochValueRequests","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"newValue","type":"bytes32"}],"name":"updateJob","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"updateMinAnswers","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_index","type":"uint256"},{"internalType":"address","name":"newValue","type":"address"}],"name":"updateOracle","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"newValues","type":"address[]"}],"name":"updateOracles","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"updateRequestsCount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"updateRequestsEvery","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newRequestsStart","type":"uint256"},{"internalType":"uint256","name":"newRequestsEvery","type":"uint256"},{"internalType":"uint256","name":"newRequestsCount","type":"uint256"}],"name":"updateRequestsInfoBatch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"updateRequestsStart","outputs":[],"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
60c060405260016004556202a30060065561546060075560046008553480156200002857600080fd5b5060405162002caf38038062002caf8339810160408190526200004b9162000208565b6000861180156200006457506001600160a01b03851615155b80156200007957506001600160a01b03841615155b801562000087575060008351115b80156200009357508115155b8015620000a1575060028110155b8015620000af575082518111155b620000ef5760405162461bcd60e51b815260206004820152600c60248201526b57524f4e475f504152414d5360a01b604482015260640160405180910390fd5b6080869052600280546001600160a01b0319166001600160a01b0387161790556001600160a01b03841660a05282516200013190600990602086019062000146565b50600a91909155600b55506200032392505050565b8280548282559060005260206000209081019282156200019e579160200282015b828111156200019e57825182546001600160a01b0319166001600160a01b0390911617825560209092019160019091019062000167565b50620001ac929150620001b0565b5090565b5b80821115620001ac5760008155600101620001b1565b6001600160a01b0381168114620001dd57600080fd5b50565b8051620001ed81620001c7565b919050565b634e487b7160e01b600052604160045260246000fd5b60008060008060008060c087890312156200022257600080fd5b865195506020808801516200023781620001c7565b60408901519096506200024a81620001c7565b60608901519095506001600160401b03808211156200026857600080fd5b818a0191508a601f8301126200027d57600080fd5b815181811115620002925762000292620001f2565b8060051b604051601f19603f83011681018181108582111715620002ba57620002ba620001f2565b60405291825284820192508381018501918d831115620002d957600080fd5b938501935b828510156200030257620002f285620001e0565b84529385019392850192620002de565b8098505050505050506080870151915060a087015190509295509295509295565b60805160a0516128e8620003c760003960008181610244015281816103f0015281816105b40152818161079301528181610929015281816109e101528181610b1e01528181610c8e01528181610fa0015281816111bd015281816112a8015281816113c3015281816115ba015281816116cf01528181611b2201528181611c0201528181611cf90152611da301526000818161039f015261197601526128e86000f3fe608060405234801561001057600080fd5b50600436106101b95760003560e01c8063a90d67a1116100f9578063cb9945a111610097578063e704fc5111610071578063e704fc51146103c1578063f5ed447c146103c9578063fbfa4b7f146103dc578063fc2a88c3146103e557600080fd5b8063cb9945a114610374578063ce43963214610387578063d5a28da31461039a57600080fd5b8063bda71d04116100d3578063bda71d041461033d578063bea1675814610350578063bef35b7914610359578063c591ff4c1461036157600080fd5b8063a90d67a114610318578063b006812c14610321578063b8feee641461033457600080fd5b806376ffb9bd1161016657806392c3c58b1161014057806392c3c58b146102d75780639496f9e3146102df5780639dbc2686146102f2578063a5c2aafd1461030557600080fd5b806376ffb9bd1461023f57806381d12c58146102665780638645f7a8146102b757600080fd5b80635614a211116101975780635614a211146101f857806358e7ec3c1461020b5780635b69a7d81461021457600080fd5b80632eb64ec4146101be57806334fa54a1146101da578063473d2f21146101ef575b600080fd5b6101c760065481565b6040519081526020015b60405180910390f35b6101ed6101e8366004612407565b6103ee565b005b6101c7600e5481565b6101ed610206366004612407565b6105b2565b6101c7600a5481565b610227610222366004612407565b610767565b6040516001600160a01b0390911681526020016101d1565b6102277f000000000000000000000000000000000000000000000000000000000000000081565b61029a610274366004612407565b6011602052600090815260409020805460019091015460ff808316926101009004169083565b6040805193151584529115156020840152908201526060016101d1565b6101c76102c5366004612407565b60106020526000908152604090205481565b6101ed610791565b6101ed6102ed366004612407565b6109df565b6101ed61030036600461245b565b610b1c565b6101ed610313366004612407565b610c8c565b6101c760075481565b6101c761032f366004612407565b610e44565b6101c7600d5481565b6101ed61034b366004612520565b610e65565b6101c7600b5481565b6101ed6111ac565b6101ed61036f366004612542565b6112a6565b6101c7610382366004612520565b611390565b6101ed61039536600461256e565b6113c1565b6101c77f000000000000000000000000000000000000000000000000000000000000000081565b6101ed61159b565b6101ed6103d7366004612407565b6116cd565b6101c760085481565b6101c7600f5481565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561044c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610470919061259e565b6001600160a01b0316336001600160a01b0316146104c25760405162461bcd60e51b815260206004820152600a60248201526927a7262cafa7aba722a960b11b60448201526064015b60405180910390fd5b610e108110156105005760405162461bcd60e51b81526020600482015260096024820152682122a627abafa6a4a760b91b60448201526064016104b9565b6201518081111561053f5760405162461bcd60e51b8152602060048201526009602482015268082849eac8abe9a82b60bb1b60448201526064016104b9565b600781905560408051818152600d918101919091527f72657175657374734576657279000000000000000000000000000000000000006060820152602081018290527f127735ae9d047cae55da37db2c8ee184c735aacd68cef068d4e70be6a41661d9906080015b60405180910390a150565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610610573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610634919061259e565b6001600160a01b0316336001600160a01b0316146106815760405162461bcd60e51b815260206004820152600a60248201526927a7262cafa7aba722a960b11b60448201526064016104b9565b60038110156106be5760405162461bcd60e51b81526020600482015260096024820152682122a627abafa6a4a760b91b60448201526064016104b9565b600a8111156106fb5760405162461bcd60e51b8152602060048201526009602482015268082849eac8abe9a82b60bb1b60448201526064016104b9565b600881905560408051818152600d918101919091527f7265717565737473436f756e74000000000000000000000000000000000000006060820152602081018290527f127735ae9d047cae55da37db2c8ee184c735aacd68cef068d4e70be6a41661d9906080016105a7565b6009818154811061077757600080fd5b6000918252602090912001546001600160a01b0316905081565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663f851a4406040518163ffffffff1660e01b8152600401602060405180830381865afa1580156107ef573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610813919061259e565b6001600160a01b0316336001600160a01b0316146108735760405162461bcd60e51b815260206004820152600a60248201527f4f4e4c595f41444d494e0000000000000000000000000000000000000000000060448201526064016104b9565b600d54806108c35760405162461bcd60e51b815260206004820152601360248201527f4e4f5f524551554553545f544f5f52455345540000000000000000000000000060448201526064016104b9565b6108cf600c600061236f565b6000600d819055600e8190555b818110156109265760006011600083600f546108f891906125d1565b8152602081019190915260400160002080549115156101000261ff00199092169190911790556001016108dc565b507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663766718086040518163ffffffff1660e01b8152600401602060405180830381865afa158015610985573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109a991906125e4565b6040518281527f605f3f824643ee56deaf2717c1581f7ad3df423365aede8e2d771b6b3a30fd2b9060200160405180910390a250565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663481c6a756040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a3d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a61919061259e565b6001600160a01b0316336001600160a01b031614610ab05760405162461bcd60e51b815260206004820152600c60248201526b27a7262cafa6a0a720a3a2a960a11b60448201526064016104b9565b80610ae75760405162461bcd60e51b8152602060048201526007602482015266056414c55455f360cc1b60448201526064016104b9565b600a8190556040518181527f9f3fa8c139076940687248e93aed7dda099cf9a90cc38c428cf3d5b6b642fdd4906020016105a7565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b7a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b9e919061259e565b6001600160a01b0316336001600160a01b031614610beb5760405162461bcd60e51b815260206004820152600a60248201526927a7262cafa7aba722a960b11b60448201526064016104b9565b600b54610bf99060026125fd565b81511015610c495760405162461bcd60e51b815260206004820152600f60248201527f41525241595f544f4f5f534d414c4c000000000000000000000000000000000060448201526064016104b9565b8051610c5c90600990602084019061238d565b507f4b806663ee384a0ada322e70cdf3fd2046424181359f2470a97a6f0cec328e9c816040516105a79190612614565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610cea573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d0e919061259e565b6001600160a01b0316336001600160a01b031614610d5b5760405162461bcd60e51b815260206004820152600a60248201526927a7262cafa7aba722a960b11b60448201526064016104b9565b610e10811015610d995760405162461bcd60e51b81526020600482015260096024820152682122a627abafa6a4a760b91b60448201526064016104b9565b62093a80811115610dd85760405162461bcd60e51b8152602060048201526009602482015268082849eac8abe9a82b60bb1b60448201526064016104b9565b600681905560408051818152600d918101919091527f72657175657374735374617274000000000000000000000000000000000000006060820152602081018290527f127735ae9d047cae55da37db2c8ee184c735aacd68cef068d4e70be6a41661d9906080016105a7565b600c8181548110610e5457600080fd5b600091825260209091200154905081565b60008281526005602052604090205482906001600160a01b03163314610ef35760405162461bcd60e51b815260206004820152602860248201527f536f75726365206d75737420626520746865206f7261636c65206f662074686560448201527f207265717565737400000000000000000000000000000000000000000000000060648201526084016104b9565b60008181526005602052604080822080546001600160a01b03191690555182917f7cc135e0cebb02c3480ae5d74d377283180a2601f8f644edf7987b009316c63a91a26000838152601060209081526040808320805490849055808452601183528184208251606081018452815460ff808216151583526101009091041615158186015260019190910154818401528251630ecce30160e31b815292519194909390926001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016926376671808926004808401939192918290030181865afa158015610fe9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061100d91906125e4565b6020808401516040808601518151921583529282018a9052810188905260608101919091529091503390849083907f5e18490ff1cb10067b5d5b0aec04678191bb80c2d229a2578526c389270027bf9060800160405180910390a4816020015161107957505050505050565b6000838152601260209081526040822080546001810182558184529190922001869055600b548154036111a2576000611100828054806020026020016040519081016040528092919081815260200182805480156110f657602002820191906000526020600020905b8154815260200190600101908083116110e2575b5050505050611891565b600c80546001810182556000919091527fdf6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c701819055604051909150859084907f2cc31a5acf549ee44228d82c08e88b92b9d332ad5193a2290a79345e113c0b4c9061116e90869086906126a2565b60405180910390a36000858152601160209081526040808320805461ff0019169055601290915281206111a09161236f565b505b505050505b505050565b600e541580801561124a57506006547f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166361a8c8c46040518163ffffffff1660e01b8152600401602060405180830381865afa158015611219573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061123d91906125e4565b61124790426125d1565b10155b1561125a57611257611955565b50565b801580156112765750600754600e5461127390426125d1565b10155b1561125757600854600d54101561128f57611257611955565b600854600c5410611257576112a2611bed565b5050565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611304573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611328919061259e565b6001600160a01b0316336001600160a01b0316146113755760405162461bcd60e51b815260206004820152600a60248201526927a7262cafa7aba722a960b11b60448201526064016104b9565b61137e83610c8c565b611387826103ee565b6111a7816105b2565b601260205281600052604060002081815481106113ac57600080fd5b90600052602060002001600091509150505481565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561141f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611443919061259e565b6001600160a01b0316336001600160a01b0316146114905760405162461bcd60e51b815260206004820152600a60248201526927a7262cafa7aba722a960b11b60448201526064016104b9565b60095482106114e15760405162461bcd60e51b815260206004820152600d60248201527f494e4445585f544f4f5f4249470000000000000000000000000000000000000060448201526064016104b9565b6001600160a01b0381166115215760405162461bcd60e51b8152602060048201526007602482015266056414c55455f360cc1b60448201526064016104b9565b8060098381548110611535576115356126c4565b60009182526020918290200180546001600160a01b0319166001600160a01b0393841617905560408051858152928416918301919091527f8323208263554cf72b3658bcdbd0f96f4ccf2c9c919fa30246aaee34537b5509910160405180910390a15050565b6008546007546115ab91906125fd565b6006546115b891906126da565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166361a8c8c46040518163ffffffff1660e01b8152600401602060405180830381865afa158015611616573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061163a91906125e4565b61164490426125d1565b10156116925760405162461bcd60e51b815260206004820152600960248201527f544f4f5f4541524c59000000000000000000000000000000000000000000000060448201526064016104b9565b600061169c611bed565b60405190915081907f446b8726654d216fe9781583f0f34cc8ac84d240bb3ad5293c10e2ff831f1eb290600090a250565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663481c6a756040518163ffffffff1660e01b8152600401602060405180830381865afa15801561172b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061174f919061259e565b6001600160a01b0316336001600160a01b03161461179e5760405162461bcd60e51b815260206004820152600c60248201526b27a7262cafa6a0a720a3a2a960a11b60448201526064016104b9565b60028110156117db5760405162461bcd60e51b81526020600482015260096024820152682122a627abafa6a4a760b91b60448201526064016104b9565b6009546117ea90600290612703565b8111156118255760405162461bcd60e51b8152602060048201526009602482015268082849eac8abe9a82b60bb1b60448201526064016104b9565b600b81905560408051818152600a918101919091527f6d696e416e7377657273000000000000000000000000000000000000000000006060820152602081018290527f127735ae9d047cae55da37db2c8ee184c735aacd68cef068d4e70be6a41661d9906080016105a7565b60006118a08260008451611e77565b600282516118ae9190612717565b156118df5781600283516118c29190612703565b815181106118d2576118d26126c4565b602002602001015161194f565b600282600284516118f09190612703565b81518110611900576119006126c4565b6020026020010151836001600286516119199190612703565b61192391906125d1565b81518110611933576119336126c4565b6020026020010151611945919061272b565b61194f9190612753565b92915050565b600061196b600a543063bda71d0460e01b611f32565b6009549091506000907f00000000000000000000000000000000000000000000000000000000000000006119a76002546001600160a01b031690565b6040516370a0823160e01b81523060048201526001600160a01b0391909116906370a0823190602401602060405180830381865afa1580156119ed573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a1191906125e4565b611a1b9190612703565b611a259190612703565b905060405180606001604052806001151581526020016001151581526020018281525060116000600f60008154611a5b90612781565b9182905550815260208082019290925260409081016000908120845181549486015161ffff1990951690151561ff0019161761010094151594909402939093178355920151600190910155600d805491611ab483612781565b909155505042600e5560005b600954811015611b1c57600f5460106000611b0360098581548110611ae757611ae76126c4565b6000918252602090912001546001600160a01b03168787611fc3565b8152602081019190915260400160002055600101611ac0565b50600f547f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663766718086040518163ffffffff1660e01b8152600401602060405180830381865afa158015611b7e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ba291906125e4565b600a5460095460408051928352602083019190915281018490527fb5f2943c67db1794f39a3b46b95086765f48c7e05d12851dc6607bcdb0bcc7a39060600160405180910390a35050565b600080600d819055506000600e8190555060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663faf33f296040518163ffffffff1660e01b8152600401602060405180830381865afa158015611c5e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c8291906125e4565b600854600c549192506000911015611c9a5781611cf3565b611cf3600c805480602002602001604051908101604052809291908181526020018280548015611ce957602002820191906000526020600020905b815481526020019060010190808311611cd5575b505050505061206b565b905060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316637361a5448460008513611d36576000611d38565b845b6040516001600160e01b031960e085901b168152600481019290925260248201526044016020604051808303816000875af1158015611d7b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d9f91906125e4565b90507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663766718086040518163ffffffff1660e01b8152600401602060405180830381865afa158015611dff573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e2391906125e4565b9350600f54847f263c5efc95bb2e2134e3fc52ae914fbd38e2381f37d95ae011a56f996578bf17600c8585604051611e5d9392919061279a565b60405180910390a3611e71600c600061236f565b50505090565b808210611e8357505050565b60008290506000848281518110611e9c57611e9c6126c4565b602002602001015190506000846001611eb591906126da565b90505b83811015611eff5781868281518110611ed357611ed36126c4565b60200260200101511215611ef757611ef78682611eef86612781565b9550856120bd565b600101611eb8565b50611f0b8585846120bd565b611f16858584611e77565b611f2b85611f258460016126da565b85611e77565b5050505050565b611f706040805160a0810182526000808252602080830182905282840182905260608084018390528451808601909552845283015290608082015290565b611fae6040805160a0810182526000808252602080830182905282840182905260608084018390528451808601909552845283015290608082015290565b611fba81868686612130565b95945050505050565b600454600090611fd48160016126da565b600455835160408086015160808701515191516000936320214ca360e11b9361200c9386938493923092918a91600191602401612805565b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff166001600160e01b0319909316929092179091529050612061868386846121ac565b9695505050505050565b60008060005b83518110156120a95783818151811061208c5761208c6126c4565b60200260200101518261209f919061272b565b9150600101612071565b5082516120b69082612753565b9392505050565b8281815181106120cf576120cf6126c4565b60200260200101518383815181106120e9576120e96126c4565b6020026020010151848481518110612103576121036126c4565b6020026020010185848151811061211c5761211c6126c4565b602090810291909101019190915252505050565b61216e6040805160a0810182526000808252602080830182905282840182905260608084018390528451808601909552845283015290608082015290565b61217e856080015161010061230a565b50508284526001600160a01b03821660208501526001600160e01b031981166040850152835b949350505050565b6040516bffffffffffffffffffffffff193060601b1660208201526034810184905260009060540160408051808303601f1901815282825280516020918201206000818152600590925291812080546001600160a01b0319166001600160a01b038a1617905590925082917fb5e6e01e79f91267dc17b4e6314d5d4d03593d2ceee0fbb452b750bd70ea5af99190a2600254604051630200057560e51b81526001600160a01b0390911690634000aea09061226f90889087908790600401612868565b6020604051808303816000875af115801561228e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122b29190612890565b6121a45760405162461bcd60e51b815260206004820152602360248201527f756e61626c6520746f207472616e73666572416e6443616c6c20746f206f7261604482015262636c6560e81b60648201526084016104b9565b60408051808201909152606081526000602082015261232a602083612717565b156123525761233a602083612717565b6123459060206125d1565b61234f90836126da565b91505b506020828101829052604080518085526000815290920101905290565b508054600082559060005260206000209081019061125791906123f2565b8280548282559060005260206000209081019282156123e2579160200282015b828111156123e257825182546001600160a01b0319166001600160a01b039091161782556020909201916001909101906123ad565b506123ee9291506123f2565b5090565b5b808211156123ee57600081556001016123f3565b60006020828403121561241957600080fd5b5035919050565b634e487b7160e01b600052604160045260246000fd5b6001600160a01b038116811461125757600080fd5b803561245681612436565b919050565b6000602080838503121561246e57600080fd5b823567ffffffffffffffff8082111561248657600080fd5b818501915085601f83011261249a57600080fd5b8135818111156124ac576124ac612420565b8060051b604051601f19603f830116810181811085821117156124d1576124d1612420565b6040529182528482019250838101850191888311156124ef57600080fd5b938501935b82851015612514576125058561244b565b845293850193928501926124f4565b98975050505050505050565b6000806040838503121561253357600080fd5b50508035926020909101359150565b60008060006060848603121561255757600080fd5b505081359360208301359350604090920135919050565b6000806040838503121561258157600080fd5b82359150602083013561259381612436565b809150509250929050565b6000602082840312156125b057600080fd5b81516120b681612436565b634e487b7160e01b600052601160045260246000fd5b8181038181111561194f5761194f6125bb565b6000602082840312156125f657600080fd5b5051919050565b808202811582820484141761194f5761194f6125bb565b6020808252825182820181905260009190848201906040850190845b818110156126555783516001600160a01b031683529284019291840191600101612630565b50909695505050505050565b600081548084526020808501945083600052602060002060005b838110156126975781548752958201956001918201910161267b565b509495945050505050565b6040815260006126b56040830185612661565b90508260208301529392505050565b634e487b7160e01b600052603260045260246000fd5b8082018082111561194f5761194f6125bb565b634e487b7160e01b600052601260045260246000fd5b600082612712576127126126ed565b500490565b600082612726576127266126ed565b500690565b808201828112600083128015821682158216171561274b5761274b6125bb565b505092915050565b600082612762576127626126ed565b600160ff1b82146000198414161561277c5761277c6125bb565b500590565b600060018201612793576127936125bb565b5060010190565b6060815260006127ad6060830186612661565b60208301949094525060400152919050565b6000815180845260005b818110156127e5576020818501810151868301820152016127c9565b506000602082860101526020601f19601f83011685010191505092915050565b60006101006001600160a01b03808c1684528a602085015289604085015280891660608501525063ffffffff60e01b871660808401528560a08401528460c08401528060e0840152612859818401856127bf565b9b9a5050505050505050505050565b6001600160a01b0384168152826020820152606060408201526000611fba60608301846127bf565b6000602082840312156128a257600080fd5b815180151581146120b657600080fdfea264697066735822122071e3b4d349b287966f2714522d1015d952ce02b46ad94b07f1ef88b7a3cacab164736f6c63430008170033000000000000000000000000000000000000000000000000000000000000006400000000000000000000000074453cf25f708ecf49be5fba66b5218379bfed2e00000000000000000000000046344456f130e9dcdea7f98cdb0e02fb9f4ab72d00000000000000000000000000000000000000000000000000000000000000c0643431373734366464363632346565326236643733316465396434636464333700000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000005000000000000000000000000f30b6ab57a5181cfbe0275c463f392ff645781a90000000000000000000000006dc9b7ccde5d2db777375bc0a597792de66cd0c00000000000000000000000007e659e8030a6e7fa12bd4826484ff46fc1978805000000000000000000000000993174a4317e3f20c1a877b6ac4931d1b2fc06470000000000000000000000004f7985407e1bd0f36c546f6a69efc4e99d9c3e47
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106101b95760003560e01c8063a90d67a1116100f9578063cb9945a111610097578063e704fc5111610071578063e704fc51146103c1578063f5ed447c146103c9578063fbfa4b7f146103dc578063fc2a88c3146103e557600080fd5b8063cb9945a114610374578063ce43963214610387578063d5a28da31461039a57600080fd5b8063bda71d04116100d3578063bda71d041461033d578063bea1675814610350578063bef35b7914610359578063c591ff4c1461036157600080fd5b8063a90d67a114610318578063b006812c14610321578063b8feee641461033457600080fd5b806376ffb9bd1161016657806392c3c58b1161014057806392c3c58b146102d75780639496f9e3146102df5780639dbc2686146102f2578063a5c2aafd1461030557600080fd5b806376ffb9bd1461023f57806381d12c58146102665780638645f7a8146102b757600080fd5b80635614a211116101975780635614a211146101f857806358e7ec3c1461020b5780635b69a7d81461021457600080fd5b80632eb64ec4146101be57806334fa54a1146101da578063473d2f21146101ef575b600080fd5b6101c760065481565b6040519081526020015b60405180910390f35b6101ed6101e8366004612407565b6103ee565b005b6101c7600e5481565b6101ed610206366004612407565b6105b2565b6101c7600a5481565b610227610222366004612407565b610767565b6040516001600160a01b0390911681526020016101d1565b6102277f00000000000000000000000046344456f130e9dcdea7f98cdb0e02fb9f4ab72d81565b61029a610274366004612407565b6011602052600090815260409020805460019091015460ff808316926101009004169083565b6040805193151584529115156020840152908201526060016101d1565b6101c76102c5366004612407565b60106020526000908152604090205481565b6101ed610791565b6101ed6102ed366004612407565b6109df565b6101ed61030036600461245b565b610b1c565b6101ed610313366004612407565b610c8c565b6101c760075481565b6101c761032f366004612407565b610e44565b6101c7600d5481565b6101ed61034b366004612520565b610e65565b6101c7600b5481565b6101ed6111ac565b6101ed61036f366004612542565b6112a6565b6101c7610382366004612520565b611390565b6101ed61039536600461256e565b6113c1565b6101c77f000000000000000000000000000000000000000000000000000000000000006481565b6101ed61159b565b6101ed6103d7366004612407565b6116cd565b6101c760085481565b6101c7600f5481565b7f00000000000000000000000046344456f130e9dcdea7f98cdb0e02fb9f4ab72d6001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561044c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610470919061259e565b6001600160a01b0316336001600160a01b0316146104c25760405162461bcd60e51b815260206004820152600a60248201526927a7262cafa7aba722a960b11b60448201526064015b60405180910390fd5b610e108110156105005760405162461bcd60e51b81526020600482015260096024820152682122a627abafa6a4a760b91b60448201526064016104b9565b6201518081111561053f5760405162461bcd60e51b8152602060048201526009602482015268082849eac8abe9a82b60bb1b60448201526064016104b9565b600781905560408051818152600d918101919091527f72657175657374734576657279000000000000000000000000000000000000006060820152602081018290527f127735ae9d047cae55da37db2c8ee184c735aacd68cef068d4e70be6a41661d9906080015b60405180910390a150565b7f00000000000000000000000046344456f130e9dcdea7f98cdb0e02fb9f4ab72d6001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610610573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610634919061259e565b6001600160a01b0316336001600160a01b0316146106815760405162461bcd60e51b815260206004820152600a60248201526927a7262cafa7aba722a960b11b60448201526064016104b9565b60038110156106be5760405162461bcd60e51b81526020600482015260096024820152682122a627abafa6a4a760b91b60448201526064016104b9565b600a8111156106fb5760405162461bcd60e51b8152602060048201526009602482015268082849eac8abe9a82b60bb1b60448201526064016104b9565b600881905560408051818152600d918101919091527f7265717565737473436f756e74000000000000000000000000000000000000006060820152602081018290527f127735ae9d047cae55da37db2c8ee184c735aacd68cef068d4e70be6a41661d9906080016105a7565b6009818154811061077757600080fd5b6000918252602090912001546001600160a01b0316905081565b7f00000000000000000000000046344456f130e9dcdea7f98cdb0e02fb9f4ab72d6001600160a01b031663f851a4406040518163ffffffff1660e01b8152600401602060405180830381865afa1580156107ef573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610813919061259e565b6001600160a01b0316336001600160a01b0316146108735760405162461bcd60e51b815260206004820152600a60248201527f4f4e4c595f41444d494e0000000000000000000000000000000000000000000060448201526064016104b9565b600d54806108c35760405162461bcd60e51b815260206004820152601360248201527f4e4f5f524551554553545f544f5f52455345540000000000000000000000000060448201526064016104b9565b6108cf600c600061236f565b6000600d819055600e8190555b818110156109265760006011600083600f546108f891906125d1565b8152602081019190915260400160002080549115156101000261ff00199092169190911790556001016108dc565b507f00000000000000000000000046344456f130e9dcdea7f98cdb0e02fb9f4ab72d6001600160a01b031663766718086040518163ffffffff1660e01b8152600401602060405180830381865afa158015610985573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109a991906125e4565b6040518281527f605f3f824643ee56deaf2717c1581f7ad3df423365aede8e2d771b6b3a30fd2b9060200160405180910390a250565b7f00000000000000000000000046344456f130e9dcdea7f98cdb0e02fb9f4ab72d6001600160a01b031663481c6a756040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a3d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a61919061259e565b6001600160a01b0316336001600160a01b031614610ab05760405162461bcd60e51b815260206004820152600c60248201526b27a7262cafa6a0a720a3a2a960a11b60448201526064016104b9565b80610ae75760405162461bcd60e51b8152602060048201526007602482015266056414c55455f360cc1b60448201526064016104b9565b600a8190556040518181527f9f3fa8c139076940687248e93aed7dda099cf9a90cc38c428cf3d5b6b642fdd4906020016105a7565b7f00000000000000000000000046344456f130e9dcdea7f98cdb0e02fb9f4ab72d6001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b7a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b9e919061259e565b6001600160a01b0316336001600160a01b031614610beb5760405162461bcd60e51b815260206004820152600a60248201526927a7262cafa7aba722a960b11b60448201526064016104b9565b600b54610bf99060026125fd565b81511015610c495760405162461bcd60e51b815260206004820152600f60248201527f41525241595f544f4f5f534d414c4c000000000000000000000000000000000060448201526064016104b9565b8051610c5c90600990602084019061238d565b507f4b806663ee384a0ada322e70cdf3fd2046424181359f2470a97a6f0cec328e9c816040516105a79190612614565b7f00000000000000000000000046344456f130e9dcdea7f98cdb0e02fb9f4ab72d6001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610cea573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d0e919061259e565b6001600160a01b0316336001600160a01b031614610d5b5760405162461bcd60e51b815260206004820152600a60248201526927a7262cafa7aba722a960b11b60448201526064016104b9565b610e10811015610d995760405162461bcd60e51b81526020600482015260096024820152682122a627abafa6a4a760b91b60448201526064016104b9565b62093a80811115610dd85760405162461bcd60e51b8152602060048201526009602482015268082849eac8abe9a82b60bb1b60448201526064016104b9565b600681905560408051818152600d918101919091527f72657175657374735374617274000000000000000000000000000000000000006060820152602081018290527f127735ae9d047cae55da37db2c8ee184c735aacd68cef068d4e70be6a41661d9906080016105a7565b600c8181548110610e5457600080fd5b600091825260209091200154905081565b60008281526005602052604090205482906001600160a01b03163314610ef35760405162461bcd60e51b815260206004820152602860248201527f536f75726365206d75737420626520746865206f7261636c65206f662074686560448201527f207265717565737400000000000000000000000000000000000000000000000060648201526084016104b9565b60008181526005602052604080822080546001600160a01b03191690555182917f7cc135e0cebb02c3480ae5d74d377283180a2601f8f644edf7987b009316c63a91a26000838152601060209081526040808320805490849055808452601183528184208251606081018452815460ff808216151583526101009091041615158186015260019190910154818401528251630ecce30160e31b815292519194909390926001600160a01b037f00000000000000000000000046344456f130e9dcdea7f98cdb0e02fb9f4ab72d16926376671808926004808401939192918290030181865afa158015610fe9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061100d91906125e4565b6020808401516040808601518151921583529282018a9052810188905260608101919091529091503390849083907f5e18490ff1cb10067b5d5b0aec04678191bb80c2d229a2578526c389270027bf9060800160405180910390a4816020015161107957505050505050565b6000838152601260209081526040822080546001810182558184529190922001869055600b548154036111a2576000611100828054806020026020016040519081016040528092919081815260200182805480156110f657602002820191906000526020600020905b8154815260200190600101908083116110e2575b5050505050611891565b600c80546001810182556000919091527fdf6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c701819055604051909150859084907f2cc31a5acf549ee44228d82c08e88b92b9d332ad5193a2290a79345e113c0b4c9061116e90869086906126a2565b60405180910390a36000858152601160209081526040808320805461ff0019169055601290915281206111a09161236f565b505b505050505b505050565b600e541580801561124a57506006547f00000000000000000000000046344456f130e9dcdea7f98cdb0e02fb9f4ab72d6001600160a01b03166361a8c8c46040518163ffffffff1660e01b8152600401602060405180830381865afa158015611219573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061123d91906125e4565b61124790426125d1565b10155b1561125a57611257611955565b50565b801580156112765750600754600e5461127390426125d1565b10155b1561125757600854600d54101561128f57611257611955565b600854600c5410611257576112a2611bed565b5050565b7f00000000000000000000000046344456f130e9dcdea7f98cdb0e02fb9f4ab72d6001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611304573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611328919061259e565b6001600160a01b0316336001600160a01b0316146113755760405162461bcd60e51b815260206004820152600a60248201526927a7262cafa7aba722a960b11b60448201526064016104b9565b61137e83610c8c565b611387826103ee565b6111a7816105b2565b601260205281600052604060002081815481106113ac57600080fd5b90600052602060002001600091509150505481565b7f00000000000000000000000046344456f130e9dcdea7f98cdb0e02fb9f4ab72d6001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561141f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611443919061259e565b6001600160a01b0316336001600160a01b0316146114905760405162461bcd60e51b815260206004820152600a60248201526927a7262cafa7aba722a960b11b60448201526064016104b9565b60095482106114e15760405162461bcd60e51b815260206004820152600d60248201527f494e4445585f544f4f5f4249470000000000000000000000000000000000000060448201526064016104b9565b6001600160a01b0381166115215760405162461bcd60e51b8152602060048201526007602482015266056414c55455f360cc1b60448201526064016104b9565b8060098381548110611535576115356126c4565b60009182526020918290200180546001600160a01b0319166001600160a01b0393841617905560408051858152928416918301919091527f8323208263554cf72b3658bcdbd0f96f4ccf2c9c919fa30246aaee34537b5509910160405180910390a15050565b6008546007546115ab91906125fd565b6006546115b891906126da565b7f00000000000000000000000046344456f130e9dcdea7f98cdb0e02fb9f4ab72d6001600160a01b03166361a8c8c46040518163ffffffff1660e01b8152600401602060405180830381865afa158015611616573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061163a91906125e4565b61164490426125d1565b10156116925760405162461bcd60e51b815260206004820152600960248201527f544f4f5f4541524c59000000000000000000000000000000000000000000000060448201526064016104b9565b600061169c611bed565b60405190915081907f446b8726654d216fe9781583f0f34cc8ac84d240bb3ad5293c10e2ff831f1eb290600090a250565b7f00000000000000000000000046344456f130e9dcdea7f98cdb0e02fb9f4ab72d6001600160a01b031663481c6a756040518163ffffffff1660e01b8152600401602060405180830381865afa15801561172b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061174f919061259e565b6001600160a01b0316336001600160a01b03161461179e5760405162461bcd60e51b815260206004820152600c60248201526b27a7262cafa6a0a720a3a2a960a11b60448201526064016104b9565b60028110156117db5760405162461bcd60e51b81526020600482015260096024820152682122a627abafa6a4a760b91b60448201526064016104b9565b6009546117ea90600290612703565b8111156118255760405162461bcd60e51b8152602060048201526009602482015268082849eac8abe9a82b60bb1b60448201526064016104b9565b600b81905560408051818152600a918101919091527f6d696e416e7377657273000000000000000000000000000000000000000000006060820152602081018290527f127735ae9d047cae55da37db2c8ee184c735aacd68cef068d4e70be6a41661d9906080016105a7565b60006118a08260008451611e77565b600282516118ae9190612717565b156118df5781600283516118c29190612703565b815181106118d2576118d26126c4565b602002602001015161194f565b600282600284516118f09190612703565b81518110611900576119006126c4565b6020026020010151836001600286516119199190612703565b61192391906125d1565b81518110611933576119336126c4565b6020026020010151611945919061272b565b61194f9190612753565b92915050565b600061196b600a543063bda71d0460e01b611f32565b6009549091506000907f00000000000000000000000000000000000000000000000000000000000000646119a76002546001600160a01b031690565b6040516370a0823160e01b81523060048201526001600160a01b0391909116906370a0823190602401602060405180830381865afa1580156119ed573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a1191906125e4565b611a1b9190612703565b611a259190612703565b905060405180606001604052806001151581526020016001151581526020018281525060116000600f60008154611a5b90612781565b9182905550815260208082019290925260409081016000908120845181549486015161ffff1990951690151561ff0019161761010094151594909402939093178355920151600190910155600d805491611ab483612781565b909155505042600e5560005b600954811015611b1c57600f5460106000611b0360098581548110611ae757611ae76126c4565b6000918252602090912001546001600160a01b03168787611fc3565b8152602081019190915260400160002055600101611ac0565b50600f547f00000000000000000000000046344456f130e9dcdea7f98cdb0e02fb9f4ab72d6001600160a01b031663766718086040518163ffffffff1660e01b8152600401602060405180830381865afa158015611b7e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ba291906125e4565b600a5460095460408051928352602083019190915281018490527fb5f2943c67db1794f39a3b46b95086765f48c7e05d12851dc6607bcdb0bcc7a39060600160405180910390a35050565b600080600d819055506000600e8190555060007f00000000000000000000000046344456f130e9dcdea7f98cdb0e02fb9f4ab72d6001600160a01b031663faf33f296040518163ffffffff1660e01b8152600401602060405180830381865afa158015611c5e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c8291906125e4565b600854600c549192506000911015611c9a5781611cf3565b611cf3600c805480602002602001604051908101604052809291908181526020018280548015611ce957602002820191906000526020600020905b815481526020019060010190808311611cd5575b505050505061206b565b905060007f00000000000000000000000046344456f130e9dcdea7f98cdb0e02fb9f4ab72d6001600160a01b0316637361a5448460008513611d36576000611d38565b845b6040516001600160e01b031960e085901b168152600481019290925260248201526044016020604051808303816000875af1158015611d7b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d9f91906125e4565b90507f00000000000000000000000046344456f130e9dcdea7f98cdb0e02fb9f4ab72d6001600160a01b031663766718086040518163ffffffff1660e01b8152600401602060405180830381865afa158015611dff573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e2391906125e4565b9350600f54847f263c5efc95bb2e2134e3fc52ae914fbd38e2381f37d95ae011a56f996578bf17600c8585604051611e5d9392919061279a565b60405180910390a3611e71600c600061236f565b50505090565b808210611e8357505050565b60008290506000848281518110611e9c57611e9c6126c4565b602002602001015190506000846001611eb591906126da565b90505b83811015611eff5781868281518110611ed357611ed36126c4565b60200260200101511215611ef757611ef78682611eef86612781565b9550856120bd565b600101611eb8565b50611f0b8585846120bd565b611f16858584611e77565b611f2b85611f258460016126da565b85611e77565b5050505050565b611f706040805160a0810182526000808252602080830182905282840182905260608084018390528451808601909552845283015290608082015290565b611fae6040805160a0810182526000808252602080830182905282840182905260608084018390528451808601909552845283015290608082015290565b611fba81868686612130565b95945050505050565b600454600090611fd48160016126da565b600455835160408086015160808701515191516000936320214ca360e11b9361200c9386938493923092918a91600191602401612805565b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff166001600160e01b0319909316929092179091529050612061868386846121ac565b9695505050505050565b60008060005b83518110156120a95783818151811061208c5761208c6126c4565b60200260200101518261209f919061272b565b9150600101612071565b5082516120b69082612753565b9392505050565b8281815181106120cf576120cf6126c4565b60200260200101518383815181106120e9576120e96126c4565b6020026020010151848481518110612103576121036126c4565b6020026020010185848151811061211c5761211c6126c4565b602090810291909101019190915252505050565b61216e6040805160a0810182526000808252602080830182905282840182905260608084018390528451808601909552845283015290608082015290565b61217e856080015161010061230a565b50508284526001600160a01b03821660208501526001600160e01b031981166040850152835b949350505050565b6040516bffffffffffffffffffffffff193060601b1660208201526034810184905260009060540160408051808303601f1901815282825280516020918201206000818152600590925291812080546001600160a01b0319166001600160a01b038a1617905590925082917fb5e6e01e79f91267dc17b4e6314d5d4d03593d2ceee0fbb452b750bd70ea5af99190a2600254604051630200057560e51b81526001600160a01b0390911690634000aea09061226f90889087908790600401612868565b6020604051808303816000875af115801561228e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122b29190612890565b6121a45760405162461bcd60e51b815260206004820152602360248201527f756e61626c6520746f207472616e73666572416e6443616c6c20746f206f7261604482015262636c6560e81b60648201526084016104b9565b60408051808201909152606081526000602082015261232a602083612717565b156123525761233a602083612717565b6123459060206125d1565b61234f90836126da565b91505b506020828101829052604080518085526000815290920101905290565b508054600082559060005260206000209081019061125791906123f2565b8280548282559060005260206000209081019282156123e2579160200282015b828111156123e257825182546001600160a01b0319166001600160a01b039091161782556020909201916001909101906123ad565b506123ee9291506123f2565b5090565b5b808211156123ee57600081556001016123f3565b60006020828403121561241957600080fd5b5035919050565b634e487b7160e01b600052604160045260246000fd5b6001600160a01b038116811461125757600080fd5b803561245681612436565b919050565b6000602080838503121561246e57600080fd5b823567ffffffffffffffff8082111561248657600080fd5b818501915085601f83011261249a57600080fd5b8135818111156124ac576124ac612420565b8060051b604051601f19603f830116810181811085821117156124d1576124d1612420565b6040529182528482019250838101850191888311156124ef57600080fd5b938501935b82851015612514576125058561244b565b845293850193928501926124f4565b98975050505050505050565b6000806040838503121561253357600080fd5b50508035926020909101359150565b60008060006060848603121561255757600080fd5b505081359360208301359350604090920135919050565b6000806040838503121561258157600080fd5b82359150602083013561259381612436565b809150509250929050565b6000602082840312156125b057600080fd5b81516120b681612436565b634e487b7160e01b600052601160045260246000fd5b8181038181111561194f5761194f6125bb565b6000602082840312156125f657600080fd5b5051919050565b808202811582820484141761194f5761194f6125bb565b6020808252825182820181905260009190848201906040850190845b818110156126555783516001600160a01b031683529284019291840191600101612630565b50909695505050505050565b600081548084526020808501945083600052602060002060005b838110156126975781548752958201956001918201910161267b565b509495945050505050565b6040815260006126b56040830185612661565b90508260208301529392505050565b634e487b7160e01b600052603260045260246000fd5b8082018082111561194f5761194f6125bb565b634e487b7160e01b600052601260045260246000fd5b600082612712576127126126ed565b500490565b600082612726576127266126ed565b500690565b808201828112600083128015821682158216171561274b5761274b6125bb565b505092915050565b600082612762576127626126ed565b600160ff1b82146000198414161561277c5761277c6125bb565b500590565b600060018201612793576127936125bb565b5060010190565b6060815260006127ad6060830186612661565b60208301949094525060400152919050565b6000815180845260005b818110156127e5576020818501810151868301820152016127c9565b506000602082860101526020601f19601f83011685010191505092915050565b60006101006001600160a01b03808c1684528a602085015289604085015280891660608501525063ffffffff60e01b871660808401528560a08401528460c08401528060e0840152612859818401856127bf565b9b9a5050505050505050505050565b6001600160a01b0384168152826020820152606060408201526000611fba60608301846127bf565b6000602082840312156128a257600080fd5b815180151581146120b657600080fdfea264697066735822122071e3b4d349b287966f2714522d1015d952ce02b46ad94b07f1ef88b7a3cacab164736f6c63430008170033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000000000000000000000000000000000000000006400000000000000000000000074453cf25f708ecf49be5fba66b5218379bfed2e00000000000000000000000046344456f130e9dcdea7f98cdb0e02fb9f4ab72d00000000000000000000000000000000000000000000000000000000000000c0643431373734366464363632346565326236643733316465396434636464333700000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000005000000000000000000000000f30b6ab57a5181cfbe0275c463f392ff645781a90000000000000000000000006dc9b7ccde5d2db777375bc0a597792de66cd0c00000000000000000000000007e659e8030a6e7fa12bd4826484ff46fc1978805000000000000000000000000993174a4317e3f20c1a877b6ac4931d1b2fc06470000000000000000000000004f7985407e1bd0f36c546f6a69efc4e99d9c3e47
-----Decoded View---------------
Arg [0] : _LINK_FEE_BALANCE_DIVIDER (uint256): 100
Arg [1] : _linkToken (address): 0x74453cf25F708EcF49be5FBA66b5218379bFEd2e
Arg [2] : _gToken (address): 0x46344456f130e9dcdeA7F98cDb0E02fB9F4ab72D
Arg [3] : _oracles (address[]): 0xF30b6Ab57a5181CfBe0275C463F392fF645781A9,0x6DC9b7CCDE5D2dB777375bc0a597792De66CD0c0,0x7E659E8030a6e7fA12bd4826484FF46FC1978805,0x993174a4317e3F20c1A877b6AC4931D1b2Fc0647,0x4f7985407E1BD0f36c546F6a69EfC4E99d9c3E47
Arg [4] : _job (bytes32): 0x6434313737343664643636323465653262366437333164653964346364643337
Arg [5] : _minAnswers (uint256): 3
-----Encoded View---------------
12 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000064
Arg [1] : 00000000000000000000000074453cf25f708ecf49be5fba66b5218379bfed2e
Arg [2] : 00000000000000000000000046344456f130e9dcdea7f98cdb0e02fb9f4ab72d
Arg [3] : 00000000000000000000000000000000000000000000000000000000000000c0
Arg [4] : 6434313737343664643636323465653262366437333164653964346364643337
Arg [5] : 0000000000000000000000000000000000000000000000000000000000000003
Arg [6] : 0000000000000000000000000000000000000000000000000000000000000005
Arg [7] : 000000000000000000000000f30b6ab57a5181cfbe0275c463f392ff645781a9
Arg [8] : 0000000000000000000000006dc9b7ccde5d2db777375bc0a597792de66cd0c0
Arg [9] : 0000000000000000000000007e659e8030a6e7fa12bd4826484ff46fc1978805
Arg [10] : 000000000000000000000000993174a4317e3f20c1a877b6ac4931d1b2fc0647
Arg [11] : 0000000000000000000000004f7985407e1bd0f36c546f6a69efc4e99d9c3e47
Loading...
Loading
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.