Feature Tip: Add private address tag to any address under My Name Tag !
More Info
Private Name Tags
ContractCreator
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
L1GraphTokenGateway
Compiler Version
v0.7.6+commit.7338295f
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity ^0.7.6; pragma abicoder v2; import { Initializable } from "@openzeppelin/contracts-upgradeable/proxy/Initializable.sol"; import { AddressUpgradeable } from "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol"; import { SafeMathUpgradeable } from "@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol"; import { L1ArbitrumMessenger } from "../arbitrum/L1ArbitrumMessenger.sol"; import { IBridge } from "../arbitrum/IBridge.sol"; import { IInbox } from "../arbitrum/IInbox.sol"; import { IOutbox } from "../arbitrum/IOutbox.sol"; import { ITokenGateway } from "../arbitrum/ITokenGateway.sol"; import { Managed } from "../governance/Managed.sol"; import { GraphTokenGateway } from "./GraphTokenGateway.sol"; import { IGraphToken } from "../token/IGraphToken.sol"; /** * @title L1 Graph Token Gateway Contract * @dev Provides the L1 side of the Ethereum-Arbitrum GRT bridge. Sends GRT to the L2 chain * by escrowing them and sending a message to the L2 gateway, and receives tokens from L2 by * releasing them from escrow. * Based on Offchain Labs' reference implementation and Livepeer's arbitrum-lpt-bridge * (See: https://github.com/OffchainLabs/arbitrum/tree/master/packages/arb-bridge-peripherals/contracts/tokenbridge * and https://github.com/livepeer/arbitrum-lpt-bridge) */ contract L1GraphTokenGateway is Initializable, GraphTokenGateway, L1ArbitrumMessenger { using SafeMathUpgradeable for uint256; /// Address of the Graph Token contract on L2 address public l2GRT; /// Address of the Arbitrum Inbox address public inbox; /// Address of the Arbitrum Gateway Router on L1 address public l1Router; /// Address of the L2GraphTokenGateway on L2 that is the counterpart of this gateway address public l2Counterpart; /// Address of the BridgeEscrow contract that holds the GRT in the bridge address public escrow; /// Addresses for which this mapping is true are allowed to send callhooks in outbound transfers mapping(address => bool) public callhookAllowlist; /// Total amount minted from L2 uint256 public totalMintedFromL2; /// Accumulated allowance for tokens minted from L2 at lastL2MintAllowanceUpdateBlock uint256 public accumulatedL2MintAllowanceSnapshot; /// Block at which new L2 allowance starts accumulating uint256 public lastL2MintAllowanceUpdateBlock; /// New L2 mint allowance per block uint256 public l2MintAllowancePerBlock; /// Emitted when an outbound transfer is initiated, i.e. tokens are deposited from L1 to L2 event DepositInitiated( address l1Token, address indexed from, address indexed to, uint256 indexed sequenceNumber, uint256 amount ); /// Emitted when an incoming transfer is finalized, i.e tokens are withdrawn from L2 to L1 event WithdrawalFinalized( address l1Token, address indexed from, address indexed to, uint256 indexed exitNum, uint256 amount ); /// Emitted when the Arbitrum Inbox and Gateway Router addresses have been updated event ArbitrumAddressesSet(address inbox, address l1Router); /// Emitted when the L2 GRT address has been updated event L2TokenAddressSet(address l2GRT); /// Emitted when the counterpart L2GraphTokenGateway address has been updated event L2CounterpartAddressSet(address l2Counterpart); /// Emitted when the escrow address has been updated event EscrowAddressSet(address escrow); /// Emitted when an address is added to the callhook allowlist event AddedToCallhookAllowlist(address newAllowlisted); /// Emitted when an address is removed from the callhook allowlist event RemovedFromCallhookAllowlist(address notAllowlisted); /// Emitted when the L2 mint allowance per block is updated event L2MintAllowanceUpdated( uint256 accumulatedL2MintAllowanceSnapshot, uint256 l2MintAllowancePerBlock, uint256 lastL2MintAllowanceUpdateBlock ); /// Emitted when tokens are minted due to an incoming transfer from L2 event TokensMintedFromL2(uint256 amount); /** * @dev Allows a function to be called only by the gateway's L2 counterpart. * The message will actually come from the Arbitrum Bridge, but the Outbox * can tell us who the sender from L2 is. */ modifier onlyL2Counterpart() { require(inbox != address(0), "INBOX_NOT_SET"); require(l2Counterpart != address(0), "L2_COUNTERPART_NOT_SET"); // a message coming from the counterpart gateway was executed by the bridge IBridge bridge = IInbox(inbox).bridge(); require(msg.sender == address(bridge), "NOT_FROM_BRIDGE"); // and the outbox reports that the L2 address of the sender is the counterpart gateway address l2ToL1Sender = IOutbox(bridge.activeOutbox()).l2ToL1Sender(); require(l2ToL1Sender == l2Counterpart, "ONLY_COUNTERPART_GATEWAY"); _; } /** * @notice Initialize the L1GraphTokenGateway contract. * @dev The contract will be paused. * Note some parameters have to be set separately as they are generally * not expected to be available at initialization time: * - inbox and l1Router using setArbitrumAddresses * - l2GRT using setL2TokenAddress * - l2Counterpart using setL2CounterpartAddress * - escrow using setEscrowAddress * - allowlisted callhook callers using addToCallhookAllowlist * - pauseGuardian using setPauseGuardian * @param _controller Address of the Controller that manages this contract */ function initialize(address _controller) external onlyImpl initializer { Managed._initialize(_controller); _paused = true; } /** * @notice Sets the addresses for L1 contracts provided by Arbitrum * @param _inbox Address of the Inbox that is part of the Arbitrum Bridge * @param _l1Router Address of the Gateway Router */ function setArbitrumAddresses(address _inbox, address _l1Router) external onlyGovernor { require(_inbox != address(0), "INVALID_INBOX"); require(_l1Router != address(0), "INVALID_L1_ROUTER"); require(!callhookAllowlist[_l1Router], "ROUTER_CANT_BE_ALLOWLISTED"); require(AddressUpgradeable.isContract(_inbox), "INBOX_MUST_BE_CONTRACT"); require(AddressUpgradeable.isContract(_l1Router), "ROUTER_MUST_BE_CONTRACT"); inbox = _inbox; l1Router = _l1Router; emit ArbitrumAddressesSet(_inbox, _l1Router); } /** * @notice Sets the address of the L2 Graph Token * @param _l2GRT Address of the GRT contract on L2 */ function setL2TokenAddress(address _l2GRT) external onlyGovernor { require(_l2GRT != address(0), "INVALID_L2_GRT"); l2GRT = _l2GRT; emit L2TokenAddressSet(_l2GRT); } /** * @notice Sets the address of the counterpart gateway on L2 * @param _l2Counterpart Address of the corresponding L2GraphTokenGateway on Arbitrum */ function setL2CounterpartAddress(address _l2Counterpart) external onlyGovernor { require(_l2Counterpart != address(0), "INVALID_L2_COUNTERPART"); l2Counterpart = _l2Counterpart; emit L2CounterpartAddressSet(_l2Counterpart); } /** * @notice Sets the address of the escrow contract on L1 * @param _escrow Address of the BridgeEscrow */ function setEscrowAddress(address _escrow) external onlyGovernor { require(_escrow != address(0), "INVALID_ESCROW"); require(AddressUpgradeable.isContract(_escrow), "MUST_BE_CONTRACT"); escrow = _escrow; emit EscrowAddressSet(_escrow); } /** * @notice Adds an address to the callhook allowlist. * This address will be allowed to include callhooks when transferring tokens. * @param _newAllowlisted Address to add to the allowlist */ function addToCallhookAllowlist(address _newAllowlisted) external onlyGovernor { require(_newAllowlisted != address(0), "INVALID_ADDRESS"); require(_newAllowlisted != l1Router, "CANT_ALLOW_ROUTER"); require(AddressUpgradeable.isContract(_newAllowlisted), "MUST_BE_CONTRACT"); require(!callhookAllowlist[_newAllowlisted], "ALREADY_ALLOWLISTED"); callhookAllowlist[_newAllowlisted] = true; emit AddedToCallhookAllowlist(_newAllowlisted); } /** * @notice Removes an address from the callhook allowlist. * This address will no longer be allowed to include callhooks when transferring tokens. * @param _notAllowlisted Address to remove from the allowlist */ function removeFromCallhookAllowlist(address _notAllowlisted) external onlyGovernor { require(_notAllowlisted != address(0), "INVALID_ADDRESS"); require(callhookAllowlist[_notAllowlisted], "NOT_ALLOWLISTED"); callhookAllowlist[_notAllowlisted] = false; emit RemovedFromCallhookAllowlist(_notAllowlisted); } /** * @dev Updates the L2 mint allowance per block * It is meant to be called _after_ the issuancePerBlock is updated in L2. * The caller should provide the new issuance per block and the block at which it was updated, * the function will automatically compute the values so that the bridge's mint allowance * correctly tracks the maximum rewards minted in L2. * @param _l2IssuancePerBlock New issuancePerBlock that has been set in L2 * @param _updateBlockNum L1 Block number at which issuancePerBlock was updated in L2 */ function updateL2MintAllowance(uint256 _l2IssuancePerBlock, uint256 _updateBlockNum) external onlyGovernor { require(_updateBlockNum < block.number, "BLOCK_MUST_BE_PAST"); require(_updateBlockNum > lastL2MintAllowanceUpdateBlock, "BLOCK_MUST_BE_INCREMENTING"); accumulatedL2MintAllowanceSnapshot = accumulatedL2MintAllowanceAtBlock(_updateBlockNum); lastL2MintAllowanceUpdateBlock = _updateBlockNum; l2MintAllowancePerBlock = _l2IssuancePerBlock; emit L2MintAllowanceUpdated( accumulatedL2MintAllowanceSnapshot, l2MintAllowancePerBlock, lastL2MintAllowanceUpdateBlock ); } /** * @dev Manually sets the parameters used to compute the L2 mint allowance * The use of this function is not recommended, use updateL2MintAllowance instead; * this one is only meant to be used as a backup recovery if a previous call to * updateL2MintAllowance was done with incorrect values. * @param _accumulatedL2MintAllowanceSnapshot Accumulated L2 mint allowance at L1 block _lastL2MintAllowanceUpdateBlock * @param _l2MintAllowancePerBlock L2 issuance per block since block number _lastL2MintAllowanceUpdateBlock * @param _lastL2MintAllowanceUpdateBlock L1 Block number at which issuancePerBlock was last updated in L2 */ function setL2MintAllowanceParametersManual( uint256 _accumulatedL2MintAllowanceSnapshot, uint256 _l2MintAllowancePerBlock, uint256 _lastL2MintAllowanceUpdateBlock ) external onlyGovernor { require(_lastL2MintAllowanceUpdateBlock < block.number, "BLOCK_MUST_BE_PAST"); accumulatedL2MintAllowanceSnapshot = _accumulatedL2MintAllowanceSnapshot; l2MintAllowancePerBlock = _l2MintAllowancePerBlock; lastL2MintAllowanceUpdateBlock = _lastL2MintAllowanceUpdateBlock; emit L2MintAllowanceUpdated( accumulatedL2MintAllowanceSnapshot, l2MintAllowancePerBlock, lastL2MintAllowanceUpdateBlock ); } /** * @notice Creates and sends a retryable ticket to transfer GRT to L2 using the Arbitrum Inbox. * The tokens are escrowed by the gateway until they are withdrawn back to L1. * The ticket must be redeemed on L2 to receive tokens at the specified address. * Note that the caller must previously allow the gateway to spend the specified amount of GRT. * @dev maxGas and gasPriceBid must be set using Arbitrum's NodeInterface.estimateRetryableTicket method. * Also note that allowlisted senders (some protocol contracts) can include additional calldata * for a callhook to be executed on the L2 side when the tokens are received. In this case, the L2 transaction * can revert if the callhook reverts, potentially locking the tokens on the bridge if the callhook * never succeeds. This requires extra care when adding contracts to the allowlist, but is necessary to ensure that * the tickets can be retried in the case of a temporary failure, and to ensure the atomicity of callhooks * with token transfers. * @param _l1Token L1 Address of the GRT contract (needed for compatibility with Arbitrum Gateway Router) * @param _to Recipient address on L2 * @param _amount Amount of tokens to transfer * @param _maxGas Gas limit for L2 execution of the ticket * @param _gasPriceBid Price per gas on L2 * @param _data Encoded maxSubmissionCost and sender address along with additional calldata * @return Sequence number of the retryable ticket created by Inbox */ function outboundTransfer( address _l1Token, address _to, uint256 _amount, uint256 _maxGas, uint256 _gasPriceBid, bytes calldata _data ) external payable override notPaused returns (bytes memory) { IGraphToken token = graphToken(); require(_amount != 0, "INVALID_ZERO_AMOUNT"); require(_l1Token == address(token), "TOKEN_NOT_GRT"); require(_to != address(0), "INVALID_DESTINATION"); // nested scopes to avoid stack too deep errors address from; uint256 seqNum; { uint256 maxSubmissionCost; bytes memory outboundCalldata; { bytes memory extraData; (from, maxSubmissionCost, extraData) = _parseOutboundData(_data); require( extraData.length == 0 || callhookAllowlist[msg.sender] == true, "CALL_HOOK_DATA_NOT_ALLOWED" ); require(maxSubmissionCost != 0, "NO_SUBMISSION_COST"); outboundCalldata = getOutboundCalldata(_l1Token, from, _to, _amount, extraData); } { L2GasParams memory gasParams = L2GasParams( maxSubmissionCost, _maxGas, _gasPriceBid ); // transfer tokens to escrow token.transferFrom(from, escrow, _amount); seqNum = sendTxToL2( inbox, l2Counterpart, from, msg.value, 0, gasParams, outboundCalldata ); } } emit DepositInitiated(_l1Token, from, _to, seqNum, _amount); return abi.encode(seqNum); } /** * @notice Receives withdrawn tokens from L2 * The equivalent tokens are released from escrow and sent to the destination. * @dev can only accept transactions coming from the L2 GRT Gateway. * The last parameter is unused but kept for compatibility with Arbitrum gateways, * and the encoded exitNum is assumed to be 0. * @param _l1Token L1 Address of the GRT contract (needed for compatibility with Arbitrum Gateway Router) * @param _from Address of the sender * @param _to Recipient address on L1 * @param _amount Amount of tokens transferred */ function finalizeInboundTransfer( address _l1Token, address _from, address _to, uint256 _amount, bytes calldata // _data, contains exitNum, unused by this contract ) external payable override notPaused onlyL2Counterpart { IGraphToken token = graphToken(); require(_l1Token == address(token), "TOKEN_NOT_GRT"); uint256 escrowBalance = token.balanceOf(escrow); if (_amount > escrowBalance) { // This will revert if trying to mint more than allowed _mintFromL2(_amount.sub(escrowBalance)); } token.transferFrom(escrow, _to, _amount); emit WithdrawalFinalized(_l1Token, _from, _to, 0, _amount); } /** * @notice Calculate the L2 address of a bridged token * @dev In our case, this would only work for GRT. * @param _l1ERC20 address of L1 GRT contract * @return L2 address of the bridged GRT token */ function calculateL2TokenAddress(address _l1ERC20) external view override returns (address) { IGraphToken token = graphToken(); if (_l1ERC20 != address(token)) { return address(0); } return l2GRT; } /** * @notice Get the address of the L2GraphTokenGateway * @dev This is added for compatibility with the Arbitrum Router's * gateway registration process. * @return Address of the L2 gateway connected to this gateway */ function counterpartGateway() external view returns (address) { return l2Counterpart; } /** * @notice Creates calldata required to create a retryable ticket * @dev encodes the target function with its params which * will be called on L2 when the retryable ticket is redeemed * @param _l1Token Address of the Graph token contract on L1 * @param _from Address on L1 from which we're transferring tokens * @param _to Address on L2 to which we're transferring tokens * @param _amount Amount of GRT to transfer * @param _data Additional call data for the L2 transaction, which must be empty unless the caller is allowlisted * @return Encoded calldata (including function selector) for the L2 transaction */ function getOutboundCalldata( address _l1Token, address _from, address _to, uint256 _amount, bytes memory _data ) public pure returns (bytes memory) { return abi.encodeWithSelector( ITokenGateway.finalizeInboundTransfer.selector, _l1Token, _from, _to, _amount, _data ); } /** * @dev Runs state validation before unpausing, reverts if * something is not set properly */ function _checksBeforeUnpause() internal view override { require(inbox != address(0), "INBOX_NOT_SET"); require(l1Router != address(0), "ROUTER_NOT_SET"); require(l2Counterpart != address(0), "L2_COUNTERPART_NOT_SET"); require(escrow != address(0), "ESCROW_NOT_SET"); } /** * @notice Decodes calldata required for migration of tokens * @dev Data must include maxSubmissionCost, extraData can be left empty. When the router * sends an outbound message, data also contains the from address. * @param _data encoded callhook data * @return Sender of the tx * @return Base ether value required to keep retryable ticket alive * @return Additional data sent to L2 */ function _parseOutboundData(bytes calldata _data) private view returns ( address, uint256, bytes memory ) { address from; uint256 maxSubmissionCost; bytes memory extraData; if (msg.sender == l1Router) { // Data encoded by the Gateway Router includes the sender address (from, extraData) = abi.decode(_data, (address, bytes)); } else { from = msg.sender; extraData = _data; } // User-encoded data contains the max retryable ticket submission cost // and additional L2 calldata (maxSubmissionCost, extraData) = abi.decode(extraData, (uint256, bytes)); return (from, maxSubmissionCost, extraData); } /** * @dev Get the accumulated L2 mint allowance at a particular block number * @param _blockNum Block at which allowance will be computed * @return The accumulated GRT amount that can be minted from L2 at the specified block */ function accumulatedL2MintAllowanceAtBlock(uint256 _blockNum) public view returns (uint256) { require(_blockNum >= lastL2MintAllowanceUpdateBlock, "INVALID_BLOCK_FOR_MINT_ALLOWANCE"); return accumulatedL2MintAllowanceSnapshot.add( l2MintAllowancePerBlock.mul(_blockNum.sub(lastL2MintAllowanceUpdateBlock)) ); } /** * @dev Mint new L1 tokens coming from L2 * This will check if the amount to mint is within the L2's mint allowance, and revert otherwise. * The tokens will be sent to the bridge escrow (from where they will then be sent to the destinatary * of the current inbound transfer). * @param _amount Number of tokens to mint */ function _mintFromL2(uint256 _amount) internal { // If we're trying to mint more than allowed, something's gone terribly wrong // (either the L2 issuance is wrong, or the Arbitrum bridge has been compromised) require(_l2MintAmountAllowed(_amount), "INVALID_L2_MINT_AMOUNT"); totalMintedFromL2 = totalMintedFromL2.add(_amount); graphToken().mint(escrow, _amount); emit TokensMintedFromL2(_amount); } /** * @dev Check if minting a certain amount of tokens from L2 is within allowance * @param _amount Number of tokens that would be minted * @return true if minting those tokens is allowed, or false if it would be over allowance */ function _l2MintAmountAllowed(uint256 _amount) internal view returns (bool) { return (totalMintedFromL2.add(_amount) <= accumulatedL2MintAllowanceAtBlock(block.number)); } }
// SPDX-License-Identifier: MIT // solhint-disable-next-line compiler-version pragma solidity >=0.4.24 <0.8.0; import "../utils/AddressUpgradeable.sol"; /** * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed * behind a proxy. Since a proxied contract can't have a constructor, it's common to move constructor logic to an * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. * * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as * possible by providing the encoded function call as the `_data` argument to {UpgradeableProxy-constructor}. * * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. */ abstract contract Initializable { /** * @dev Indicates that the contract has been initialized. */ bool private _initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool private _initializing; /** * @dev Modifier to protect an initializer function from being invoked twice. */ modifier initializer() { require(_initializing || _isConstructor() || !_initialized, "Initializable: contract is already initialized"); bool isTopLevelCall = !_initializing; if (isTopLevelCall) { _initializing = true; _initialized = true; } _; if (isTopLevelCall) { _initializing = false; } } /// @dev Returns true if and only if the function is running in the constructor function _isConstructor() private view returns (bool) { return !AddressUpgradeable.isContract(address(this)); } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.2 <0.8.0; /** * @dev Collection of functions related to the address type */ library AddressUpgradeable { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize, which returns 0 for contracts in // construction, since the code is only stored at the end of the // constructor execution. uint256 size; // solhint-disable-next-line no-inline-assembly assembly { size := extcodesize(account) } return size > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); // solhint-disable-next-line avoid-low-level-calls, avoid-call-value (bool success, ) = recipient.call{ value: amount }(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain`call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.call{ value: value }(data); return _verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.staticcall(data); return _verifyCallResult(success, returndata, errorMessage); } function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly // solhint-disable-next-line no-inline-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; /** * @dev Wrappers over Solidity's arithmetic operations with added overflow * checks. * * Arithmetic operations in Solidity wrap on overflow. This can easily result * in bugs, because programmers usually assume that an overflow raises an * error, which is the standard behavior in high level programming languages. * `SafeMath` restores this intuition by reverting the transaction when an * operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. */ library SafeMathUpgradeable { /** * @dev Returns the addition of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) { uint256 c = a + b; if (c < a) return (false, 0); return (true, c); } /** * @dev Returns the substraction of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) { if (b > a) return (false, 0); return (true, a - b); } /** * @dev Returns the multiplication of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) return (true, 0); uint256 c = a * b; if (c / a != b) return (false, 0); return (true, c); } /** * @dev Returns the division of two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) { if (b == 0) return (false, 0); return (true, a / b); } /** * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) { if (b == 0) return (false, 0); return (true, a % b); } /** * @dev Returns the addition of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * * - Addition cannot overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a, "SafeMath: addition overflow"); return c; } /** * @dev Returns the subtraction of two unsigned integers, reverting on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { require(b <= a, "SafeMath: subtraction overflow"); return a - b; } /** * @dev Returns the multiplication of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `*` operator. * * Requirements: * * - Multiplication cannot overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256) { if (a == 0) return 0; uint256 c = a * b; require(c / a == b, "SafeMath: multiplication overflow"); return c; } /** * @dev Returns the integer division of two unsigned integers, reverting on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { require(b > 0, "SafeMath: division by zero"); return a / b; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { require(b > 0, "SafeMath: modulo by zero"); return a % b; } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {trySub}. * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b <= a, errorMessage); return a - b; } /** * @dev Returns the integer division of two unsigned integers, reverting with custom message on * division by zero. The result is rounded towards zero. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryDiv}. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b > 0, errorMessage); return a / b; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting with custom message when dividing by zero. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryMod}. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b > 0, errorMessage); return a % b; } }
// SPDX-License-Identifier: Apache-2.0 /* * Copyright 2020, Offchain Labs, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * Originally copied from: * https://github.com/OffchainLabs/arbitrum/tree/e3a6307ad8a2dc2cad35728a2a9908cfd8dd8ef9/packages/arb-bridge-peripherals * * MODIFIED from Offchain Labs' implementation: * - Changed solidity version to 0.7.6 ([email protected]) * */ pragma solidity ^0.7.6; import "./IInbox.sol"; import "./IOutbox.sol"; /// @notice L1 utility contract to assist with L1 <=> L2 interactions /// @dev this is an abstract contract instead of library so the functions can be easily overriden when testing abstract contract L1ArbitrumMessenger { event TxToL2(address indexed _from, address indexed _to, uint256 indexed _seqNum, bytes _data); struct L2GasParams { uint256 _maxSubmissionCost; uint256 _maxGas; uint256 _gasPriceBid; } function sendTxToL2( address _inbox, address _to, address _user, uint256 _l1CallValue, uint256 _l2CallValue, L2GasParams memory _l2GasParams, bytes memory _data ) internal virtual returns (uint256) { // alternative function entry point when struggling with the stack size return sendTxToL2( _inbox, _to, _user, _l1CallValue, _l2CallValue, _l2GasParams._maxSubmissionCost, _l2GasParams._maxGas, _l2GasParams._gasPriceBid, _data ); } function sendTxToL2( address _inbox, address _to, address _user, uint256 _l1CallValue, uint256 _l2CallValue, uint256 _maxSubmissionCost, uint256 _maxGas, uint256 _gasPriceBid, bytes memory _data ) internal virtual returns (uint256) { uint256 seqNum = IInbox(_inbox).createRetryableTicket{ value: _l1CallValue }( _to, _l2CallValue, _maxSubmissionCost, _user, _user, _maxGas, _gasPriceBid, _data ); emit TxToL2(_user, _to, seqNum, _data); return seqNum; } function getBridge(address _inbox) internal view virtual returns (IBridge) { return IInbox(_inbox).bridge(); } /// @dev the l2ToL1Sender behaves as the tx.origin, the msg.sender should be validated to protect against reentrancies function getL2ToL1Sender(address _inbox) internal view virtual returns (address) { IOutbox outbox = IOutbox(getBridge(_inbox).activeOutbox()); address l2ToL1Sender = outbox.l2ToL1Sender(); require(l2ToL1Sender != address(0), "NO_SENDER"); return l2ToL1Sender; } }
// SPDX-License-Identifier: Apache-2.0 /* * Copyright 2021, Offchain Labs, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * Originally copied from: * https://github.com/OffchainLabs/arbitrum/tree/e3a6307ad8a2dc2cad35728a2a9908cfd8dd8ef9/packages/arb-bridge-eth * * MODIFIED from Offchain Labs' implementation: * - Changed solidity version to 0.7.6 ([email protected]) * */ pragma solidity ^0.7.6; interface IBridge { event MessageDelivered( uint256 indexed messageIndex, bytes32 indexed beforeInboxAcc, address inbox, uint8 kind, address sender, bytes32 messageDataHash ); event BridgeCallTriggered( address indexed outbox, address indexed destAddr, uint256 amount, bytes data ); event InboxToggle(address indexed inbox, bool enabled); event OutboxToggle(address indexed outbox, bool enabled); function deliverMessageToInbox( uint8 kind, address sender, bytes32 messageDataHash ) external payable returns (uint256); function executeCall( address destAddr, uint256 amount, bytes calldata data ) external returns (bool success, bytes memory returnData); // These are only callable by the admin function setInbox(address inbox, bool enabled) external; function setOutbox(address inbox, bool enabled) external; // View functions function activeOutbox() external view returns (address); function allowedInboxes(address inbox) external view returns (bool); function allowedOutboxes(address outbox) external view returns (bool); function inboxAccs(uint256 index) external view returns (bytes32); function messageCount() external view returns (uint256); }
// SPDX-License-Identifier: Apache-2.0 /* * Copyright 2021, Offchain Labs, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * Originally copied from: * https://github.com/OffchainLabs/arbitrum/tree/e3a6307ad8a2dc2cad35728a2a9908cfd8dd8ef9/packages/arb-bridge-eth * * MODIFIED from Offchain Labs' implementation: * - Changed solidity version to 0.7.6 ([email protected]) * */ pragma solidity ^0.7.6; import "./IBridge.sol"; import "./IMessageProvider.sol"; interface IInbox is IMessageProvider { function sendL2Message(bytes calldata messageData) external returns (uint256); function sendUnsignedTransaction( uint256 maxGas, uint256 gasPriceBid, uint256 nonce, address destAddr, uint256 amount, bytes calldata data ) external returns (uint256); function sendContractTransaction( uint256 maxGas, uint256 gasPriceBid, address destAddr, uint256 amount, bytes calldata data ) external returns (uint256); function sendL1FundedUnsignedTransaction( uint256 maxGas, uint256 gasPriceBid, uint256 nonce, address destAddr, bytes calldata data ) external payable returns (uint256); function sendL1FundedContractTransaction( uint256 maxGas, uint256 gasPriceBid, address destAddr, bytes calldata data ) external payable returns (uint256); function createRetryableTicket( address destAddr, uint256 arbTxCallValue, uint256 maxSubmissionCost, address submissionRefundAddress, address valueRefundAddress, uint256 maxGas, uint256 gasPriceBid, bytes calldata data ) external payable returns (uint256); function depositEth(uint256 maxSubmissionCost) external payable returns (uint256); function bridge() external view returns (IBridge); function pauseCreateRetryables() external; function unpauseCreateRetryables() external; function startRewriteAddress() external; function stopRewriteAddress() external; }
// SPDX-License-Identifier: Apache-2.0 /* * Copyright 2021, Offchain Labs, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * Originally copied from: * https://github.com/OffchainLabs/arbitrum/tree/e3a6307ad8a2dc2cad35728a2a9908cfd8dd8ef9/packages/arb-bridge-eth * * MODIFIED from Offchain Labs' implementation: * - Changed solidity version to 0.7.6 ([email protected]) * */ pragma solidity ^0.7.6; interface IOutbox { event OutboxEntryCreated( uint256 indexed batchNum, uint256 outboxEntryIndex, bytes32 outputRoot, uint256 numInBatch ); event OutBoxTransactionExecuted( address indexed destAddr, address indexed l2Sender, uint256 indexed outboxEntryIndex, uint256 transactionIndex ); function l2ToL1Sender() external view returns (address); function l2ToL1Block() external view returns (uint256); function l2ToL1EthBlock() external view returns (uint256); function l2ToL1Timestamp() external view returns (uint256); function l2ToL1BatchNum() external view returns (uint256); function l2ToL1OutputId() external view returns (bytes32); function processOutgoingMessages(bytes calldata sendsData, uint256[] calldata sendLengths) external; function outboxEntryExists(uint256 batchNum) external view returns (bool); }
// SPDX-License-Identifier: Apache-2.0 /* * Copyright 2020, Offchain Labs, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * Originally copied from: * https://github.com/OffchainLabs/arbitrum/tree/e3a6307ad8a2dc2cad35728a2a9908cfd8dd8ef9/packages/arb-bridge-peripherals * * MODIFIED from Offchain Labs' implementation: * - Changed solidity version to 0.7.6 ([email protected]) * */ pragma solidity ^0.7.6; interface ITokenGateway { /// @notice event deprecated in favor of DepositInitiated and WithdrawalInitiated // event OutboundTransferInitiated( // address token, // address indexed _from, // address indexed _to, // uint256 indexed _transferId, // uint256 _amount, // bytes _data // ); /// @notice event deprecated in favor of DepositFinalized and WithdrawalFinalized // event InboundTransferFinalized( // address token, // address indexed _from, // address indexed _to, // uint256 indexed _transferId, // uint256 _amount, // bytes _data // ); function outboundTransfer( address _token, address _to, uint256 _amount, uint256 _maxGas, uint256 _gasPriceBid, bytes calldata _data ) external payable returns (bytes memory); function finalizeInboundTransfer( address _token, address _from, address _to, uint256 _amount, bytes calldata _data ) external payable; /** * @notice Calculate the address used when bridging an ERC20 token * @dev the L1 and L2 address oracles may not always be in sync. * For example, a custom token may have been registered but not deployed or the contract self destructed. * @param l1ERC20 address of L1 token * @return L2 address of a bridged ERC20 token */ function calculateL2TokenAddress(address l1ERC20) external view returns (address); }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity ^0.7.6; import { IController } from "./IController.sol"; import { ICuration } from "../curation/ICuration.sol"; import { IEpochManager } from "../epochs/IEpochManager.sol"; import { IRewardsManager } from "../rewards/IRewardsManager.sol"; import { IStaking } from "../staking/IStaking.sol"; import { IGraphToken } from "../token/IGraphToken.sol"; import { ITokenGateway } from "../arbitrum/ITokenGateway.sol"; import { IManaged } from "./IManaged.sol"; /** * @title Graph Managed contract * @dev The Managed contract provides an interface to interact with the Controller. * It also provides local caching for contract addresses. This mechanism relies on calling the * public `syncAllContracts()` function whenever a contract changes in the controller. * * Inspired by Livepeer: * https://github.com/livepeer/protocol/blob/streamflow/contracts/Controller.sol */ abstract contract Managed is IManaged { // -- State -- /// Controller that contract is registered with IController public controller; /// @dev Cache for the addresses of the contracts retrieved from the controller mapping(bytes32 => address) private _addressCache; /// @dev Gap for future storage variables uint256[10] private __gap; // Immutables bytes32 private immutable CURATION = keccak256("Curation"); bytes32 private immutable EPOCH_MANAGER = keccak256("EpochManager"); bytes32 private immutable REWARDS_MANAGER = keccak256("RewardsManager"); bytes32 private immutable STAKING = keccak256("Staking"); bytes32 private immutable GRAPH_TOKEN = keccak256("GraphToken"); bytes32 private immutable GRAPH_TOKEN_GATEWAY = keccak256("GraphTokenGateway"); // -- Events -- /// Emitted when a contract parameter has been updated event ParameterUpdated(string param); /// Emitted when the controller address has been set event SetController(address controller); /// Emitted when contract with `nameHash` is synced to `contractAddress`. event ContractSynced(bytes32 indexed nameHash, address contractAddress); // -- Modifiers -- /** * @dev Revert if the controller is paused or partially paused */ function _notPartialPaused() internal view { require(!controller.paused(), "Paused"); require(!controller.partialPaused(), "Partial-paused"); } /** * @dev Revert if the controller is paused */ function _notPaused() internal view virtual { require(!controller.paused(), "Paused"); } /** * @dev Revert if the caller is not the governor */ function _onlyGovernor() internal view { require(msg.sender == controller.getGovernor(), "Only Controller governor"); } /** * @dev Revert if the caller is not the Controller */ function _onlyController() internal view { require(msg.sender == address(controller), "Caller must be Controller"); } /** * @dev Revert if the controller is paused or partially paused */ modifier notPartialPaused() { _notPartialPaused(); _; } /** * @dev Revert if the controller is paused */ modifier notPaused() { _notPaused(); _; } /** * @dev Revert if the caller is not the Controller */ modifier onlyController() { _onlyController(); _; } /** * @dev Revert if the caller is not the governor */ modifier onlyGovernor() { _onlyGovernor(); _; } // -- Functions -- /** * @dev Initialize a Managed contract * @param _controller Address for the Controller that manages this contract */ function _initialize(address _controller) internal { _setController(_controller); } /** * @notice Set Controller. Only callable by current controller. * @param _controller Controller contract address */ function setController(address _controller) external override onlyController { _setController(_controller); } /** * @dev Set controller. * @param _controller Controller contract address */ function _setController(address _controller) internal { require(_controller != address(0), "Controller must be set"); controller = IController(_controller); emit SetController(_controller); } /** * @dev Return Curation interface * @return Curation contract registered with Controller */ function curation() internal view returns (ICuration) { return ICuration(_resolveContract(CURATION)); } /** * @dev Return EpochManager interface * @return Epoch manager contract registered with Controller */ function epochManager() internal view returns (IEpochManager) { return IEpochManager(_resolveContract(EPOCH_MANAGER)); } /** * @dev Return RewardsManager interface * @return Rewards manager contract registered with Controller */ function rewardsManager() internal view returns (IRewardsManager) { return IRewardsManager(_resolveContract(REWARDS_MANAGER)); } /** * @dev Return Staking interface * @return Staking contract registered with Controller */ function staking() internal view returns (IStaking) { return IStaking(_resolveContract(STAKING)); } /** * @dev Return GraphToken interface * @return Graph token contract registered with Controller */ function graphToken() internal view returns (IGraphToken) { return IGraphToken(_resolveContract(GRAPH_TOKEN)); } /** * @dev Return GraphTokenGateway (L1 or L2) interface * @return Graph token gateway contract registered with Controller */ function graphTokenGateway() internal view returns (ITokenGateway) { return ITokenGateway(_resolveContract(GRAPH_TOKEN_GATEWAY)); } /** * @dev Resolve a contract address from the cache or the Controller if not found * @param _nameHash keccak256 hash of the contract name * @return Address of the contract */ function _resolveContract(bytes32 _nameHash) internal view returns (address) { address contractAddress = _addressCache[_nameHash]; if (contractAddress == address(0)) { contractAddress = controller.getContractProxy(_nameHash); } return contractAddress; } /** * @dev Cache a contract address from the Controller registry. * @param _name Name of the contract to sync into the cache */ function _syncContract(string memory _name) internal { bytes32 nameHash = keccak256(abi.encodePacked(_name)); address contractAddress = controller.getContractProxy(nameHash); if (_addressCache[nameHash] != contractAddress) { _addressCache[nameHash] = contractAddress; emit ContractSynced(nameHash, contractAddress); } } /** * @notice Sync protocol contract addresses from the Controller registry * @dev This function will cache all the contracts using the latest addresses * Anyone can call the function whenever a Proxy contract change in the * controller to ensure the protocol is using the latest version */ function syncAllContracts() external { _syncContract("Curation"); _syncContract("EpochManager"); _syncContract("RewardsManager"); _syncContract("Staking"); _syncContract("GraphToken"); _syncContract("GraphTokenGateway"); } }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity ^0.7.6; import { GraphUpgradeable } from "../upgrades/GraphUpgradeable.sol"; import { ITokenGateway } from "../arbitrum/ITokenGateway.sol"; import { Pausable } from "../governance/Pausable.sol"; import { Managed } from "../governance/Managed.sol"; /** * @title L1/L2 Graph Token Gateway * @dev This includes everything that's shared between the L1 and L2 sides of the bridge. */ abstract contract GraphTokenGateway is GraphUpgradeable, Pausable, Managed, ITokenGateway { /// @dev Storage gap added in case we need to add state variables to this contract uint256[50] private __gap; /** * @dev Check if the caller is the Controller's governor or this contract's pause guardian. */ modifier onlyGovernorOrGuardian() { require( msg.sender == controller.getGovernor() || msg.sender == pauseGuardian, "Only Governor or Guardian" ); _; } /** * @notice Change the Pause Guardian for this contract * @param _newPauseGuardian The address of the new Pause Guardian */ function setPauseGuardian(address _newPauseGuardian) external onlyGovernor { require(_newPauseGuardian != address(0), "PauseGuardian must be set"); _setPauseGuardian(_newPauseGuardian); } /** * @notice Change the paused state of the contract * @param _newPaused New value for the pause state (true means the transfers will be paused) */ function setPaused(bool _newPaused) external onlyGovernorOrGuardian { if (!_newPaused) { _checksBeforeUnpause(); } _setPaused(_newPaused); } /** * @notice Getter to access paused state of this contract * @return True if the contract is paused, false otherwise */ function paused() external view returns (bool) { return _paused; } /** * @dev Override the default pausing from Managed to allow pausing this * particular contract instead of pausing from the Controller. */ function _notPaused() internal view override { require(!_paused, "Paused (contract)"); } /** * @dev Runs state validation before unpausing, reverts if * something is not set properly */ function _checksBeforeUnpause() internal view virtual; }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity ^0.7.6; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; interface IGraphToken is IERC20 { // -- Mint and Burn -- function burn(uint256 amount) external; function burnFrom(address _from, uint256 amount) external; function mint(address _to, uint256 _amount) external; // -- Mint Admin -- function addMinter(address _account) external; function removeMinter(address _account) external; function renounceMinter() external; function isMinter(address _account) external view returns (bool); // -- Permit -- function permit( address _owner, address _spender, uint256 _value, uint256 _deadline, uint8 _v, bytes32 _r, bytes32 _s ) external; // -- Allowance -- function increaseAllowance(address spender, uint256 addedValue) external returns (bool); function decreaseAllowance(address spender, uint256 subtractedValue) external returns (bool); }
// SPDX-License-Identifier: Apache-2.0 /* * Copyright 2021, Offchain Labs, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * Originally copied from: * https://github.com/OffchainLabs/arbitrum/tree/e3a6307ad8a2dc2cad35728a2a9908cfd8dd8ef9/packages/arb-bridge-eth * * MODIFIED from Offchain Labs' implementation: * - Changed solidity version to 0.7.6 ([email protected]) * */ pragma solidity ^0.7.6; interface IMessageProvider { event InboxMessageDelivered(uint256 indexed messageNum, bytes data); event InboxMessageDeliveredFromOrigin(uint256 indexed messageNum); }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity >=0.6.12 <0.8.0; interface IController { function getGovernor() external view returns (address); // -- Registry -- function setContractProxy(bytes32 _id, address _contractAddress) external; function unsetContractProxy(bytes32 _id) external; function updateController(bytes32 _id, address _controller) external; function getContractProxy(bytes32 _id) external view returns (address); // -- Pausing -- function setPartialPaused(bool _partialPaused) external; function setPaused(bool _paused) external; function setPauseGuardian(address _newPauseGuardian) external; function paused() external view returns (bool); function partialPaused() external view returns (bool); }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity ^0.7.6; import "./IGraphCurationToken.sol"; interface ICuration { // -- Configuration -- function setDefaultReserveRatio(uint32 _defaultReserveRatio) external; function setMinimumCurationDeposit(uint256 _minimumCurationDeposit) external; function setCurationTaxPercentage(uint32 _percentage) external; function setCurationTokenMaster(address _curationTokenMaster) external; // -- Curation -- function mint( bytes32 _subgraphDeploymentID, uint256 _tokensIn, uint256 _signalOutMin ) external returns (uint256, uint256); function burn( bytes32 _subgraphDeploymentID, uint256 _signalIn, uint256 _tokensOutMin ) external returns (uint256); function collect(bytes32 _subgraphDeploymentID, uint256 _tokens) external; // -- Getters -- function isCurated(bytes32 _subgraphDeploymentID) external view returns (bool); function getCuratorSignal(address _curator, bytes32 _subgraphDeploymentID) external view returns (uint256); function getCurationPoolSignal(bytes32 _subgraphDeploymentID) external view returns (uint256); function getCurationPoolTokens(bytes32 _subgraphDeploymentID) external view returns (uint256); function tokensToSignal(bytes32 _subgraphDeploymentID, uint256 _tokensIn) external view returns (uint256, uint256); function signalToTokens(bytes32 _subgraphDeploymentID, uint256 _signalIn) external view returns (uint256); function curationTaxPercentage() external view returns (uint32); }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity ^0.7.6; interface IEpochManager { // -- Configuration -- function setEpochLength(uint256 _epochLength) external; // -- Epochs function runEpoch() external; // -- Getters -- function isCurrentEpochRun() external view returns (bool); function blockNum() external view returns (uint256); function blockHash(uint256 _block) external view returns (bytes32); function currentEpoch() external view returns (uint256); function currentEpochBlock() external view returns (uint256); function currentEpochBlockSinceStart() external view returns (uint256); function epochsSince(uint256 _epoch) external view returns (uint256); function epochsSinceUpdate() external view returns (uint256); }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity ^0.7.6; interface IRewardsManager { /** * @dev Stores accumulated rewards and snapshots related to a particular SubgraphDeployment. */ struct Subgraph { uint256 accRewardsForSubgraph; uint256 accRewardsForSubgraphSnapshot; uint256 accRewardsPerSignalSnapshot; uint256 accRewardsPerAllocatedToken; } // -- Config -- function setIssuancePerBlock(uint256 _issuancePerBlock) external; function setMinimumSubgraphSignal(uint256 _minimumSubgraphSignal) external; // -- Denylist -- function setSubgraphAvailabilityOracle(address _subgraphAvailabilityOracle) external; function setDenied(bytes32 _subgraphDeploymentID, bool _deny) external; function setDeniedMany(bytes32[] calldata _subgraphDeploymentID, bool[] calldata _deny) external; function isDenied(bytes32 _subgraphDeploymentID) external view returns (bool); // -- Getters -- function getNewRewardsPerSignal() external view returns (uint256); function getAccRewardsPerSignal() external view returns (uint256); function getAccRewardsForSubgraph(bytes32 _subgraphDeploymentID) external view returns (uint256); function getAccRewardsPerAllocatedToken(bytes32 _subgraphDeploymentID) external view returns (uint256, uint256); function getRewards(address _allocationID) external view returns (uint256); // -- Updates -- function updateAccRewardsPerSignal() external returns (uint256); function takeRewards(address _allocationID) external returns (uint256); // -- Hooks -- function onSubgraphSignalUpdate(bytes32 _subgraphDeploymentID) external returns (uint256); function onSubgraphAllocationUpdate(bytes32 _subgraphDeploymentID) external returns (uint256); }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity >=0.6.12 <0.8.0; pragma abicoder v2; import "./IStakingData.sol"; interface IStaking is IStakingData { // -- Allocation Data -- /** * @dev Possible states an allocation can be * States: * - Null = indexer == address(0) * - Active = not Null && tokens > 0 * - Closed = Active && closedAtEpoch != 0 * - Finalized = Closed && closedAtEpoch + channelDisputeEpochs > now() * - Claimed = not Null && tokens == 0 */ enum AllocationState { Null, Active, Closed, Finalized, Claimed } // -- Configuration -- function setMinimumIndexerStake(uint256 _minimumIndexerStake) external; function setThawingPeriod(uint32 _thawingPeriod) external; function setCurationPercentage(uint32 _percentage) external; function setProtocolPercentage(uint32 _percentage) external; function setChannelDisputeEpochs(uint32 _channelDisputeEpochs) external; function setMaxAllocationEpochs(uint32 _maxAllocationEpochs) external; function setRebateRatio(uint32 _alphaNumerator, uint32 _alphaDenominator) external; function setDelegationRatio(uint32 _delegationRatio) external; function setDelegationParameters( uint32 _indexingRewardCut, uint32 _queryFeeCut, uint32 _cooldownBlocks ) external; function setDelegationParametersCooldown(uint32 _blocks) external; function setDelegationUnbondingPeriod(uint32 _delegationUnbondingPeriod) external; function setDelegationTaxPercentage(uint32 _percentage) external; function setSlasher(address _slasher, bool _allowed) external; function setAssetHolder(address _assetHolder, bool _allowed) external; // -- Operation -- function setOperator(address _operator, bool _allowed) external; function isOperator(address _operator, address _indexer) external view returns (bool); // -- Staking -- function stake(uint256 _tokens) external; function stakeTo(address _indexer, uint256 _tokens) external; function unstake(uint256 _tokens) external; function slash( address _indexer, uint256 _tokens, uint256 _reward, address _beneficiary ) external; function withdraw() external; function setRewardsDestination(address _destination) external; // -- Delegation -- function delegate(address _indexer, uint256 _tokens) external returns (uint256); function undelegate(address _indexer, uint256 _shares) external returns (uint256); function withdrawDelegated(address _indexer, address _newIndexer) external returns (uint256); // -- Channel management and allocations -- function allocate( bytes32 _subgraphDeploymentID, uint256 _tokens, address _allocationID, bytes32 _metadata, bytes calldata _proof ) external; function allocateFrom( address _indexer, bytes32 _subgraphDeploymentID, uint256 _tokens, address _allocationID, bytes32 _metadata, bytes calldata _proof ) external; function closeAllocation(address _allocationID, bytes32 _poi) external; function closeAllocationMany(CloseAllocationRequest[] calldata _requests) external; function closeAndAllocate( address _oldAllocationID, bytes32 _poi, address _indexer, bytes32 _subgraphDeploymentID, uint256 _tokens, address _allocationID, bytes32 _metadata, bytes calldata _proof ) external; function collect(uint256 _tokens, address _allocationID) external; function claim(address _allocationID, bool _restake) external; function claimMany(address[] calldata _allocationID, bool _restake) external; // -- Getters and calculations -- function hasStake(address _indexer) external view returns (bool); function getIndexerStakedTokens(address _indexer) external view returns (uint256); function getIndexerCapacity(address _indexer) external view returns (uint256); function getAllocation(address _allocationID) external view returns (Allocation memory); function getAllocationState(address _allocationID) external view returns (AllocationState); function isAllocation(address _allocationID) external view returns (bool); function getSubgraphAllocatedTokens(bytes32 _subgraphDeploymentID) external view returns (uint256); function getDelegation(address _indexer, address _delegator) external view returns (Delegation memory); function isDelegator(address _indexer, address _delegator) external view returns (bool); }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity ^0.7.6; interface IManaged { function setController(address _controller) external; }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity ^0.7.6; import "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol"; interface IGraphCurationToken is IERC20Upgradeable { function initialize(address _owner) external; function burnFrom(address _account, uint256 _amount) external; function mint(address _to, uint256 _amount) external; }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20Upgradeable { /** * @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 `recipient`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address recipient, 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 `sender` to `recipient` 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 sender, address recipient, uint256 amount) external returns (bool); /** * @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); }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity >=0.6.12 <0.8.0; interface IStakingData { /** * @dev Allocate GRT tokens for the purpose of serving queries of a subgraph deployment * An allocation is created in the allocate() function and consumed in claim() */ struct Allocation { address indexer; bytes32 subgraphDeploymentID; uint256 tokens; // Tokens allocated to a SubgraphDeployment uint256 createdAtEpoch; // Epoch when it was created uint256 closedAtEpoch; // Epoch when it was closed uint256 collectedFees; // Collected fees for the allocation uint256 effectiveAllocation; // Effective allocation when closed uint256 accRewardsPerAllocatedToken; // Snapshot used for reward calc } /** * @dev Represents a request to close an allocation with a specific proof of indexing. * This is passed when calling closeAllocationMany to define the closing parameters for * each allocation. */ struct CloseAllocationRequest { address allocationID; bytes32 poi; } // -- Delegation Data -- /** * @dev Delegation pool information. One per indexer. */ struct DelegationPool { uint32 cooldownBlocks; // Blocks to wait before updating parameters uint32 indexingRewardCut; // in PPM uint32 queryFeeCut; // in PPM uint256 updatedAtBlock; // Block when the pool was last updated uint256 tokens; // Total tokens as pool reserves uint256 shares; // Total shares minted in the pool mapping(address => Delegation) delegators; // Mapping of delegator => Delegation } /** * @dev Individual delegation data of a delegator in a pool. */ struct Delegation { uint256 shares; // Shares owned by a delegator in the pool uint256 tokensLocked; // Tokens locked for undelegation uint256 tokensLockedUntil; // Block when locked tokens can be withdrawn } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @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 `recipient`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address recipient, 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 `sender` to `recipient` 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 sender, address recipient, uint256 amount) external returns (bool); /** * @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); }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity ^0.7.6; import { IGraphProxy } from "./IGraphProxy.sol"; /** * @title Graph Upgradeable * @dev This contract is intended to be inherited from upgradeable contracts. */ abstract contract GraphUpgradeable { /** * @dev Storage slot with the address of the current implementation. * This is the keccak-256 hash of "eip1967.proxy.implementation" subtracted by 1, and is * validated in the constructor. */ bytes32 internal constant IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; /** * @dev Check if the caller is the proxy admin. */ modifier onlyProxyAdmin(IGraphProxy _proxy) { require(msg.sender == _proxy.admin(), "Caller must be the proxy admin"); _; } /** * @dev Check if the caller is the implementation. */ modifier onlyImpl() { require(msg.sender == _implementation(), "Only implementation"); _; } /** * @dev Returns the current implementation. * @return impl Address of the current implementation */ function _implementation() internal view returns (address impl) { bytes32 slot = IMPLEMENTATION_SLOT; // solhint-disable-next-line no-inline-assembly assembly { impl := sload(slot) } } /** * @notice Accept to be an implementation of proxy. * @param _proxy Proxy to accept */ function acceptProxy(IGraphProxy _proxy) external onlyProxyAdmin(_proxy) { _proxy.acceptUpgrade(); } /** * @notice Accept to be an implementation of proxy and then call a function from the new * implementation as specified by `_data`, which should be an encoded function call. This is * useful to initialize new storage variables in the proxied contract. * @param _proxy Proxy to accept * @param _data Calldata for the initialization function call (including selector) */ function acceptProxyAndCall(IGraphProxy _proxy, bytes calldata _data) external onlyProxyAdmin(_proxy) { _proxy.acceptUpgradeAndCall(_data); } }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity ^0.7.6; abstract contract Pausable { /** * @dev "Partial paused" pauses exit and enter functions for GRT, but not internal * functions, such as allocating */ bool internal _partialPaused; /** * @dev Paused will pause all major protocol functions */ bool internal _paused; /// Timestamp for the last time the partial pause was set uint256 public lastPausePartialTime; /// Timestamp for the last time the full pause was set uint256 public lastPauseTime; /// Pause guardian is a separate entity from the governor that can /// pause and unpause the protocol, fully or partially address public pauseGuardian; /// Emitted when the partial pause state changed event PartialPauseChanged(bool isPaused); /// Emitted when the full pause state changed event PauseChanged(bool isPaused); /// Emitted when the pause guardian is changed event NewPauseGuardian(address indexed oldPauseGuardian, address indexed pauseGuardian); /** * @dev Change the partial paused state of the contract * @param _toPause New value for the partial pause state (true means the contracts will be partially paused) */ function _setPartialPaused(bool _toPause) internal { if (_toPause == _partialPaused) { return; } _partialPaused = _toPause; if (_partialPaused) { lastPausePartialTime = block.timestamp; } emit PartialPauseChanged(_partialPaused); } /** * @dev Change the paused state of the contract * @param _toPause New value for the pause state (true means the contracts will be paused) */ function _setPaused(bool _toPause) internal { if (_toPause == _paused) { return; } _paused = _toPause; if (_paused) { lastPauseTime = block.timestamp; } emit PauseChanged(_paused); } /** * @dev Change the Pause Guardian * @param newPauseGuardian The address of the new Pause Guardian */ function _setPauseGuardian(address newPauseGuardian) internal { address oldPauseGuardian = pauseGuardian; pauseGuardian = newPauseGuardian; emit NewPauseGuardian(oldPauseGuardian, pauseGuardian); } }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity ^0.7.6; interface IGraphProxy { function admin() external returns (address); function setAdmin(address _newAdmin) external; function implementation() external returns (address); function pendingImplementation() external returns (address); function upgradeTo(address _newImplementation) external; function acceptUpgrade() external; function acceptUpgradeAndCall(bytes calldata data) external; }
{ "optimizer": { "enabled": true, "runs": 200 }, "metadata": { "useLiteralContent": true }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newAllowlisted","type":"address"}],"name":"AddedToCallhookAllowlist","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"inbox","type":"address"},{"indexed":false,"internalType":"address","name":"l1Router","type":"address"}],"name":"ArbitrumAddressesSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"nameHash","type":"bytes32"},{"indexed":false,"internalType":"address","name":"contractAddress","type":"address"}],"name":"ContractSynced","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"l1Token","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"sequenceNumber","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"DepositInitiated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"escrow","type":"address"}],"name":"EscrowAddressSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"l2Counterpart","type":"address"}],"name":"L2CounterpartAddressSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"accumulatedL2MintAllowanceSnapshot","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"l2MintAllowancePerBlock","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"lastL2MintAllowanceUpdateBlock","type":"uint256"}],"name":"L2MintAllowanceUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"l2GRT","type":"address"}],"name":"L2TokenAddressSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"oldPauseGuardian","type":"address"},{"indexed":true,"internalType":"address","name":"pauseGuardian","type":"address"}],"name":"NewPauseGuardian","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"param","type":"string"}],"name":"ParameterUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"isPaused","type":"bool"}],"name":"PartialPauseChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"isPaused","type":"bool"}],"name":"PauseChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"notAllowlisted","type":"address"}],"name":"RemovedFromCallhookAllowlist","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"controller","type":"address"}],"name":"SetController","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"TokensMintedFromL2","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_from","type":"address"},{"indexed":true,"internalType":"address","name":"_to","type":"address"},{"indexed":true,"internalType":"uint256","name":"_seqNum","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"_data","type":"bytes"}],"name":"TxToL2","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"l1Token","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"exitNum","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"WithdrawalFinalized","type":"event"},{"inputs":[{"internalType":"contract IGraphProxy","name":"_proxy","type":"address"}],"name":"acceptProxy","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IGraphProxy","name":"_proxy","type":"address"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"acceptProxyAndCall","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_blockNum","type":"uint256"}],"name":"accumulatedL2MintAllowanceAtBlock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"accumulatedL2MintAllowanceSnapshot","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_newAllowlisted","type":"address"}],"name":"addToCallhookAllowlist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_l1ERC20","type":"address"}],"name":"calculateL2TokenAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"callhookAllowlist","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"controller","outputs":[{"internalType":"contract IController","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"counterpartGateway","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"escrow","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_l1Token","type":"address"},{"internalType":"address","name":"_from","type":"address"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"finalizeInboundTransfer","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_l1Token","type":"address"},{"internalType":"address","name":"_from","type":"address"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"getOutboundCalldata","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"inbox","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_controller","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"l1Router","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"l2Counterpart","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"l2GRT","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"l2MintAllowancePerBlock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastL2MintAllowanceUpdateBlock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastPausePartialTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastPauseTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_l1Token","type":"address"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256","name":"_maxGas","type":"uint256"},{"internalType":"uint256","name":"_gasPriceBid","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"outboundTransfer","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"pauseGuardian","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_notAllowlisted","type":"address"}],"name":"removeFromCallhookAllowlist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_inbox","type":"address"},{"internalType":"address","name":"_l1Router","type":"address"}],"name":"setArbitrumAddresses","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_controller","type":"address"}],"name":"setController","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_escrow","type":"address"}],"name":"setEscrowAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_l2Counterpart","type":"address"}],"name":"setL2CounterpartAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_accumulatedL2MintAllowanceSnapshot","type":"uint256"},{"internalType":"uint256","name":"_l2MintAllowancePerBlock","type":"uint256"},{"internalType":"uint256","name":"_lastL2MintAllowanceUpdateBlock","type":"uint256"}],"name":"setL2MintAllowanceParametersManual","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_l2GRT","type":"address"}],"name":"setL2TokenAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newPauseGuardian","type":"address"}],"name":"setPauseGuardian","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_newPaused","type":"bool"}],"name":"setPaused","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"syncAllContracts","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"totalMintedFromL2","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_l2IssuancePerBlock","type":"uint256"},{"internalType":"uint256","name":"_updateBlockNum","type":"uint256"}],"name":"updateL2MintAllowance","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
6101406040527fe6876326c1291dfcbbd3864a6816d698cd591defc7aa2153d7f9c4c04016c89f6080527fc713c3df6d14cdf946460395d09af88993ee2b948b1a808161494e32c5f6706360a0527f966f1e8d8d8014e05f6ec4a57138da9be1f7c5a7f802928a18072f7c5318076160c0527f1df41cd916959d1163dc8f0671a666ea8a3e434c13e40faef527133b5d16703460e0527f45fc200c7e4544e457d3c5709bfe0d520442c30bbcbdaede89e8d4a4bbc19247610100527fd362cac9cb75c10d67bcc0b7eeb0b1ef48bb5420b556c092d4fd7f758816fcf0610120523480156100eb57600080fd5b5060805160a05160c05160e051610100516101205161304561011c6000395080611d3d5250505050506130456000f3fe60806040526004361061020f5760003560e01c80638f438f1711610118578063cac60872116100a0578063d6866ea51161006f578063d6866ea514610595578063ddeb63b5146105aa578063e2fdcc17146105ca578063f77c4791146105df578063fb0e722b146105f45761020f565b8063cac608721461052d578063d2ce7d6514610542578063d426f70014610555578063d653b022146105755761020f565b8063a0c76a96116100e7578063a0c76a9614610480578063a2594d82146104ad578063a7e28d48146104cd578063b83d696e146104ed578063c4d66de81461050d5761020f565b80638f438f171461040b57806391b4ded91461042b57806392eefe9b146104405780639ce7abe5146104605761020f565b806348bde20c1161019b578063721302631161016a578063721302631461038c57806373aea0ae146103ac5780637fee3d43146103c15780638e7c8efe146103e15780638f3112c5146103f65761020f565b806348bde20c146103205780634c381870146103405780635c975abb146103555780636cda3798146103775761020f565b806322ca40a8116101e257806322ca40a8146102a157806324a3d622146102c15780632db09c1c146102e35780632e567b36146102f8578063407395e01461030b5761020f565b8063011e68e31461021457806311dd71291461023657806316c38b3c146102615780631c5b777614610281575b600080fd5b34801561022057600080fd5b5061023461022f36600461254e565b610609565b005b34801561024257600080fd5b5061024b610696565b6040516102589190612f08565b60405180910390f35b34801561026d57600080fd5b5061023461027c366004612790565b61069c565b34801561028d57600080fd5b5061024b61029c36600461281b565b610794565b3480156102ad57600080fd5b506102346102bc36600461254e565b6107ed565b3480156102cd57600080fd5b506102d6610866565b6040516102589190612942565b3480156102ef57600080fd5b506102d6610875565b61023461030636600461260c565b610884565b34801561031757600080fd5b506102d6610c56565b34801561032c57600080fd5b5061023461033b36600461254e565b610c65565b34801561034c57600080fd5b506102d6610cd1565b34801561036157600080fd5b5061036a610ce0565b60405161025891906129f3565b34801561038357600080fd5b5061024b610cf0565b34801561039857600080fd5b506102346103a73660046128eb565b610cf6565b3480156103b857600080fd5b5061024b610d6d565b3480156103cd57600080fd5b506102346103dc3660046128ca565b610d73565b3480156103ed57600080fd5b506102d6610e11565b34801561040257600080fd5b5061024b610e20565b34801561041757600080fd5b5061023461042636600461254e565b610e26565b34801561043757600080fd5b5061024b610f33565b34801561044c57600080fd5b5061023461045b36600461254e565b610f39565b34801561046c57600080fd5b5061023461047b3660046127c8565b610f4a565b34801561048c57600080fd5b506104a061049b36600461268f565b6110a0565b60405161025891906129fe565b3480156104b957600080fd5b506102346104c836600461254e565b611100565b3480156104d957600080fd5b506102d66104e836600461254e565b61121b565b3480156104f957600080fd5b5061036a61050836600461254e565b61125e565b34801561051957600080fd5b5061023461052836600461254e565b611273565b34801561053957600080fd5b5061024b611395565b6104a061055036600461270c565b61139b565b34801561056157600080fd5b5061023461057036600461254e565b611606565b34801561058157600080fd5b506102346105903660046125d4565b6116bc565b3480156105a157600080fd5b506102346117f5565b3480156105b657600080fd5b506102346105c536600461254e565b611901565b3480156105d657600080fd5b506102d661199f565b3480156105eb57600080fd5b506102d66119ae565b34801561060057600080fd5b506102d66119bd565b6106116119cc565b6001600160a01b0381166106405760405162461bcd60e51b815260040161063790612eb0565b60405180910390fd5b604280546001600160a01b0319166001600160a01b0383161790556040517f9a6e2b45041fa2939015ac2bd7e80b890de28d7154ef04b0f52a94fa4e88091d9061068b908390612942565b60405180910390a150565b604b5481565b6004805460408051634fc07d7560e01b815290516001600160a01b0390921692634fc07d75928282019260209290829003018186803b1580156106de57600080fd5b505afa1580156106f2573d6000803e3d6000fd5b505050506040513d602081101561070857600080fd5b50516001600160a01b031633148061072a57506003546001600160a01b031633145b61077b576040805162461bcd60e51b815260206004820152601960248201527f4f6e6c7920476f7665726e6f72206f7220477561726469616e00000000000000604482015290519081900360640190fd5b8061078857610788611a96565b61079181611b36565b50565b6000604a548210156107b85760405162461bcd60e51b815260040161063790612b7e565b6107e56107dc6107d3604a5485611bc790919063ffffffff16565b604b5490611c29565b60495490611c89565b90505b919050565b6107f56119cc565b6001600160a01b03811661081b5760405162461bcd60e51b815260040161063790612cca565b604580546001600160a01b0319166001600160a01b0383161790556040517f75d3e58d9088e31d57a8da4c52196f9d30e8f6fd45543bbe506679e2bef8eaa79061068b908390612942565b6003546001600160a01b031681565b6045546001600160a01b031690565b61088c611ce3565b6043546001600160a01b03166108b45760405162461bcd60e51b815260040161063790612b57565b6045546001600160a01b03166108dc5760405162461bcd60e51b815260040161063790612ed8565b604354604080516373c6754960e11b815290516000926001600160a01b03169163e78cea92916004808301926020929190829003018186803b15801561092157600080fd5b505afa158015610935573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610959919061256a565b9050336001600160a01b038216146109835760405162461bcd60e51b815260040161063790612a6a565b6000816001600160a01b031663ab5d89436040518163ffffffff1660e01b815260040160206040518083038186803b1580156109be57600080fd5b505afa1580156109d2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109f6919061256a565b6001600160a01b03166380648b026040518163ffffffff1660e01b815260040160206040518083038186803b158015610a2e57600080fd5b505afa158015610a42573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a66919061256a565b6045549091506001600160a01b03808316911614610a965760405162461bcd60e51b815260040161063790612e79565b6000610aa0611d36565b9050806001600160a01b0316896001600160a01b031614610ad35760405162461bcd60e51b815260040161063790612e2b565b6046546040516370a0823160e01b81526000916001600160a01b03808516926370a0823192610b06921690600401612942565b60206040518083038186803b158015610b1e57600080fd5b505afa158015610b32573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b569190612833565b905080871115610b7257610b72610b6d8883611bc7565b611d66565b6046546040516323b872dd60e01b81526001600160a01b03848116926323b872dd92610ba892909116908c908c906004016129b6565b602060405180830381600087803b158015610bc257600080fd5b505af1158015610bd6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bfa91906127ac565b506000886001600160a01b03168a6001600160a01b03167f891afe029c75c4f8c5855fc3480598bc5a53739344f6ae575bdb7ea2a79f56b38d8b604051610c429291906129da565b60405180910390a450505050505050505050565b6044546001600160a01b031681565b610c6d6119cc565b6001600160a01b038116610cc8576040805162461bcd60e51b815260206004820152601960248201527f5061757365477561726469616e206d7573742062652073657400000000000000604482015290519081900360640190fd5b61079181611e37565b6042546001600160a01b031681565b6000546301000000900460ff1690565b60015481565b610cfe6119cc565b438110610d1d5760405162461bcd60e51b815260040161063790612c67565b6049839055604b829055604a8190556040517fbfdf0135edba030abcdb9dfcdd3856c401a97acac62e96ba34714ae9cff0ebe690610d6090859085908590612f11565b60405180910390a1505050565b604a5481565b610d7b6119cc565b438110610d9a5760405162461bcd60e51b815260040161063790612c67565b604a548111610dbb5760405162461bcd60e51b815260040161063790612abc565b610dc481610794565b6049819055604a829055604b8390556040517fbfdf0135edba030abcdb9dfcdd3856c401a97acac62e96ba34714ae9cff0ebe691610e059185908590612f11565b60405180910390a15050565b6045546001600160a01b031681565b60485481565b610e2e6119cc565b6001600160a01b038116610e545760405162461bcd60e51b815260040161063790612a11565b6044546001600160a01b0382811691161415610e825760405162461bcd60e51b815260040161063790612e00565b610e8b81611e8b565b610ea75760405162461bcd60e51b815260040161063790612d77565b6001600160a01b03811660009081526047602052604090205460ff1615610ee05760405162461bcd60e51b815260040161063790612c3a565b6001600160a01b03811660009081526047602052604090819020805460ff19166001179055517ff3b329c349ad69ad25f0137ff68c2eaf5ad22fc53cd7a1cfe40a52b19499c1d29061068b908390612942565b60025481565b610f41611e91565b61079181611ef0565b82806001600160a01b031663f851a4406040518163ffffffff1660e01b8152600401602060405180830381600087803b158015610f8657600080fd5b505af1158015610f9a573d6000803e3d6000fd5b505050506040513d6020811015610fb057600080fd5b50516001600160a01b0316331461100e576040805162461bcd60e51b815260206004820152601e60248201527f43616c6c6572206d757374206265207468652070726f78792061646d696e0000604482015290519081900360640190fd5b60405163623faf6160e01b8152602060048201908152602482018490526001600160a01b0386169163623faf619186918691908190604401848480828437600081840152601f19601f8201169050808301925050509350505050600060405180830381600087803b15801561108257600080fd5b505af1158015611096573d6000803e3d6000fd5b5050505050505050565b6060632e567b3660e01b86868686866040516024016110c3959493929190612970565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152905095945050505050565b80806001600160a01b031663f851a4406040518163ffffffff1660e01b8152600401602060405180830381600087803b15801561113c57600080fd5b505af1158015611150573d6000803e3d6000fd5b505050506040513d602081101561116657600080fd5b50516001600160a01b031633146111c4576040805162461bcd60e51b815260206004820152601e60248201527f43616c6c6572206d757374206265207468652070726f78792061646d696e0000604482015290519081900360640190fd5b816001600160a01b03166359fc20bb6040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156111ff57600080fd5b505af1158015611213573d6000803e3d6000fd5b505050505050565b600080611226611d36565b9050806001600160a01b0316836001600160a01b03161461124b5760009150506107e8565b50506042546001600160a01b0316919050565b60476020526000908152604090205460ff1681565b61127b611f98565b6001600160a01b0316336001600160a01b0316146112d6576040805162461bcd60e51b815260206004820152601360248201527227b7363c9034b6b83632b6b2b73a30ba34b7b760691b604482015290519081900360640190fd5b600054610100900460ff16806112ef57506112ef611fbd565b806112fd575060005460ff16155b6113385760405162461bcd60e51b815260040180806020018281038252602e815260200180612fc1602e913960400191505060405180910390fd5b600054610100900460ff16158015611363576000805460ff1961ff0019909116610100171660011790555b61136c82610f41565b6000805463ff000000191663010000001790558015611391576000805461ff00191690555b5050565b60495481565b60606113a5611ce3565b60006113af611d36565b9050866113ce5760405162461bcd60e51b815260040161063790612b2a565b806001600160a01b0316896001600160a01b0316146113ff5760405162461bcd60e51b815260040161063790612e2b565b6001600160a01b0388166114255760405162461bcd60e51b815260040161063790612cfa565b60008060006060806114378989611fce565b80519297509094509150158061146157503360009081526047602052604090205460ff1615156001145b61147d5760405162461bcd60e51b815260040161063790612dc9565b8261149a5760405162461bcd60e51b815260040161063790612c0e565b6114a78e868f8f856110a0565b915050600060405180606001604052808481526020018c81526020018b8152509050856001600160a01b03166323b872dd86604660009054906101000a90046001600160a01b03168f6040518463ffffffff1660e01b815260040161150e939291906129b6565b602060405180830381600087803b15801561152857600080fd5b505af115801561153c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061156091906127ac565b50604354604554611583916001600160a01b039081169116873460008688612067565b9350505050808a6001600160a01b0316836001600160a01b03167fb8910b9960c443aac3240b98585384e3a6f109fbf6969e264c3f183d69aba7e18e8d6040516115ce9291906129da565b60405180910390a4806040516020016115e79190612f08565b6040516020818303038152906040529350505050979650505050505050565b61160e6119cc565b6001600160a01b0381166116345760405162461bcd60e51b815260040161063790612a11565b6001600160a01b03811660009081526047602052604090205460ff1661166c5760405162461bcd60e51b815260040161063790612a93565b6001600160a01b03811660009081526047602052604090819020805460ff19169055517f418f3ae472ec14bb195924385de80a9e9303050c823552568af2adb8388d9d099061068b908390612942565b6116c46119cc565b6001600160a01b0382166116ea5760405162461bcd60e51b815260040161063790612e52565b6001600160a01b0381166117105760405162461bcd60e51b815260040161063790612be3565b6001600160a01b03811660009081526047602052604090205460ff16156117495760405162461bcd60e51b815260040161063790612c93565b61175282611e8b565b61176e5760405162461bcd60e51b815260040161063790612bb3565b61177781611e8b565b6117935760405162461bcd60e51b815260040161063790612af3565b604380546001600160a01b038085166001600160a01b03199283161790925560448054928416929091169190911790556040517fc5f09bf22bb39edf3e4c5f4fd5c4809125836ddc8a0937099d04f53f31eda23d90610e059084908490612956565b61181e6040518060400160405280600881526020016721bab930ba34b7b760c11b815250612092565b61184b6040518060400160405280600c81526020016b22b837b1b426b0b730b3b2b960a11b815250612092565b61187a6040518060400160405280600e81526020016d2932bbb0b93239a6b0b730b3b2b960911b815250612092565b6118a2604051806040016040528060078152602001665374616b696e6760c81b815250612092565b6118cd6040518060400160405280600a81526020016923b930b8342a37b5b2b760b11b815250612092565b6118ff604051806040016040528060118152602001704772617068546f6b656e4761746577617960781b815250612092565b565b6119096119cc565b6001600160a01b03811661192f5760405162461bcd60e51b815260040161063790612d4f565b61193881611e8b565b6119545760405162461bcd60e51b815260040161063790612d77565b604680546001600160a01b0319166001600160a01b0383161790556040517f14229a64f0a7328601813f0f794bb1dbc59363f1ed61c2f957d00517e6140e189061068b908390612942565b6046546001600160a01b031681565b6004546001600160a01b031681565b6043546001600160a01b031681565b6004805460408051634fc07d7560e01b815290516001600160a01b0390921692634fc07d75928282019260209290829003018186803b158015611a0e57600080fd5b505afa158015611a22573d6000803e3d6000fd5b505050506040513d6020811015611a3857600080fd5b50516001600160a01b031633146118ff576040805162461bcd60e51b815260206004820152601860248201527f4f6e6c7920436f6e74726f6c6c657220676f7665726e6f720000000000000000604482015290519081900360640190fd5b6043546001600160a01b0316611abe5760405162461bcd60e51b815260040161063790612b57565b6044546001600160a01b0316611ae65760405162461bcd60e51b815260040161063790612d27565b6045546001600160a01b0316611b0e5760405162461bcd60e51b815260040161063790612ed8565b6046546001600160a01b03166118ff5760405162461bcd60e51b815260040161063790612da1565b600060039054906101000a900460ff1615158115151415611b5657610791565b6000805463ff000000191663010000008315158102919091179182905560ff91041615611b8257426002555b60005460408051630100000090920460ff1615158252517f8fb6c181ee25a520cf3dd6565006ef91229fcfe5a989566c2a3b8c115570cec5916020908290030190a150565b600082821115611c1e576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b508082035b92915050565b600082611c3857506000611c23565b82820282848281611c4557fe5b0414611c825760405162461bcd60e51b8152600401808060200182810382526021815260200180612fef6021913960400191505060405180910390fd5b9392505050565b600082820183811015611c82576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b6000546301000000900460ff16156118ff576040805162461bcd60e51b81526020600482015260116024820152705061757365642028636f6e74726163742960781b604482015290519081900360640190fd5b6000611d617f0000000000000000000000000000000000000000000000000000000000000000612204565b905090565b611d6f8161229e565b611d8b5760405162461bcd60e51b815260040161063790612a3a565b604854611d989082611c89565b604855611da3611d36565b6046546040516340c10f1960e01b81526001600160a01b03928316926340c10f1992611dd69291169085906004016129da565b600060405180830381600087803b158015611df057600080fd5b505af1158015611e04573d6000803e3d6000fd5b505050507f4f8ca17191c10265804777143e4643b72f8a4c63ad6a973e2ed85532194abf828160405161068b9190612f08565b600380546001600160a01b038381166001600160a01b03198316179283905560405191811692169082907f0613b6ee6a04f0d09f390e4d9318894b9f6ac7fd83897cd8d18896ba579c401e90600090a35050565b3b151590565b6004546001600160a01b031633146118ff576040805162461bcd60e51b815260206004820152601960248201527f43616c6c6572206d75737420626520436f6e74726f6c6c657200000000000000604482015290519081900360640190fd5b6001600160a01b038116611f44576040805162461bcd60e51b815260206004820152601660248201527510dbdb9d1c9bdb1b195c881b5d5cdd081899481cd95d60521b604482015290519081900360640190fd5b600480546001600160a01b0383166001600160a01b0319909116811790915560408051918252517f4ff638452bbf33c012645d18ae6f05515ff5f2d1dfb0cece8cbf018c60903f709181900360200190a150565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6000611fc830611e8b565b15905090565b60445460009081906060908290819083906001600160a01b031633141561200557611ffb87890189612586565b9093509050612042565b33925087878080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509293505050505b80806020019051810190612056919061284b565b939650945091925050509250925092565b60006120868888888888886000015189602001518a604001518a6122be565b98975050505050505050565b6000816040516020018082805190602001908083835b602083106120c75780518252601f1990920191602091820191016120a8565b51815160209384036101000a60001901801990921691161790526040805192909401828103601f1901835280855282519282019290922060048054637bb20d2f60e11b85529084018290529451909750600096506001600160a01b03909416945063f7641a5e93602480840194509192909190829003018186803b15801561214e57600080fd5b505afa158015612162573d6000803e3d6000fd5b505050506040513d602081101561217857600080fd5b50516000838152600560205260409020549091506001600160a01b038083169116146121ff5760008281526005602090815260409182902080546001600160a01b0319166001600160a01b0385169081179091558251908152915184927fd0e7a942b1fc38c411c4f53d153ba14fd24542a6a35ebacd9b6afca1a154e20692908290030190a25b505050565b6000818152600560205260408120546001600160a01b0316806107e5576004805460408051637bb20d2f60e11b8152928301869052516001600160a01b039091169163f7641a5e916024808301926020929190829003018186803b15801561226b57600080fd5b505afa15801561227f573d6000803e3d6000fd5b505050506040513d602081101561229557600080fd5b50519392505050565b60006122a943610794565b6048546122b69084611c89565b111592915050565b6000808a6001600160a01b031663679b6ded898c8a8a8e8f8c8c8c6040518a63ffffffff1660e01b815260040180896001600160a01b03168152602001888152602001878152602001866001600160a01b03168152602001856001600160a01b0316815260200184815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b8381101561236a578181015183820152602001612352565b50505050905090810190601f1680156123975780820380516001836020036101000a031916815260200191505b5099505050505050505050506020604051808303818588803b1580156123bc57600080fd5b505af11580156123d0573d6000803e3d6000fd5b50505050506040513d60208110156123e757600080fd5b81019080805190602001909291905050509050808a6001600160a01b03168a6001600160a01b03167fc1d1490cf25c3b40d600dfb27c7680340ed1ab901b7e8f3551280968a3b372b0866040518080602001828103825283818151815260200191508051906020019080838360005b8381101561246e578181015183820152602001612456565b50505050905090810190601f16801561249b5780820380516001836020036101000a031916815260200191505b509250505060405180910390a49a9950505050505050505050565b60008083601f8401126124c7578182fd5b50813567ffffffffffffffff8111156124de578182fd5b6020830191508360208285010111156124f657600080fd5b9250929050565b600082601f83011261250d578081fd5b813561252061251b82612f4b565b612f27565b818152846020838601011115612534578283fd5b816020850160208301379081016020019190915292915050565b60006020828403121561255f578081fd5b8135611c8281612f9d565b60006020828403121561257b578081fd5b8151611c8281612f9d565b60008060408385031215612598578081fd5b82356125a381612f9d565b9150602083013567ffffffffffffffff8111156125be578182fd5b6125ca858286016124fd565b9150509250929050565b600080604083850312156125e6578182fd5b82356125f181612f9d565b9150602083013561260181612f9d565b809150509250929050565b60008060008060008060a08789031215612624578182fd5b863561262f81612f9d565b9550602087013561263f81612f9d565b9450604087013561264f81612f9d565b935060608701359250608087013567ffffffffffffffff811115612671578283fd5b61267d89828a016124b6565b979a9699509497509295939492505050565b600080600080600060a086880312156126a6578081fd5b85356126b181612f9d565b945060208601356126c181612f9d565b935060408601356126d181612f9d565b925060608601359150608086013567ffffffffffffffff8111156126f3578182fd5b6126ff888289016124fd565b9150509295509295909350565b600080600080600080600060c0888a031215612726578081fd5b873561273181612f9d565b9650602088013561274181612f9d565b955060408801359450606088013593506080880135925060a088013567ffffffffffffffff811115612771578182fd5b61277d8a828b016124b6565b989b979a50959850939692959293505050565b6000602082840312156127a1578081fd5b8135611c8281612fb2565b6000602082840312156127bd578081fd5b8151611c8281612fb2565b6000806000604084860312156127dc578081fd5b83356127e781612f9d565b9250602084013567ffffffffffffffff811115612802578182fd5b61280e868287016124b6565b9497909650939450505050565b60006020828403121561282c578081fd5b5035919050565b600060208284031215612844578081fd5b5051919050565b6000806040838503121561285d578182fd5b82519150602083015167ffffffffffffffff81111561287a578182fd5b8301601f8101851361288a578182fd5b805161289861251b82612f4b565b8181528660208385010111156128ac578384fd5b6128bd826020830160208601612f6d565b8093505050509250929050565b600080604083850312156128dc578182fd5b50508035926020909101359150565b6000806000606084860312156128ff578081fd5b505081359360208301359350604090920135919050565b6000815180845261292e816020860160208601612f6d565b601f01601f19169290920160200192915050565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b6001600160a01b0386811682528581166020830152841660408201526060810183905260a0608082018190526000906129ab90830184612916565b979650505050505050565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b03929092168252602082015260400190565b901515815260200190565b600060208252611c826020830184612916565b6020808252600f908201526e494e56414c49445f4144445245535360881b604082015260600190565b6020808252601690820152751253959053125117d30c97d352539517d05353d5539560521b604082015260600190565b6020808252600f908201526e4e4f545f46524f4d5f42524944474560881b604082015260600190565b6020808252600f908201526e1393d517d0531313d5d31254d51151608a1b604082015260600190565b6020808252601a908201527f424c4f434b5f4d5553545f42455f494e4352454d454e54494e47000000000000604082015260600190565b60208082526017908201527f524f555445525f4d5553545f42455f434f4e5452414354000000000000000000604082015260600190565b6020808252601390820152721253959053125117d6915493d7d05353d55395606a1b604082015260600190565b6020808252600d908201526c12539093d617d393d517d4d155609a1b604082015260600190565b6020808252818101527f494e56414c49445f424c4f434b5f464f525f4d494e545f414c4c4f57414e4345604082015260600190565b60208082526016908201527512539093d617d35554d517d09157d0d3d395149050d560521b604082015260600190565b60208082526011908201527024a72b20a624a22fa618afa927aaaa22a960791b604082015260600190565b6020808252601290820152711393d7d4d550935254d4d253d397d0d3d4d560721b604082015260600190565b6020808252601390820152721053149150511657d0531313d5d31254d51151606a1b604082015260600190565b602080825260129082015271109313d0d2d7d35554d517d09157d41054d560721b604082015260600190565b6020808252601a908201527f524f555445525f43414e545f42455f414c4c4f574c4953544544000000000000604082015260600190565b6020808252601690820152751253959053125117d30c97d0d3d5539511549410549560521b604082015260600190565b60208082526013908201527224a72b20a624a22fa222a9aa24a720aa24a7a760691b604082015260600190565b6020808252600e908201526d1493d555115497d393d517d4d15560921b604082015260600190565b6020808252600e908201526d494e56414c49445f455343524f5760901b604082015260600190565b60208082526010908201526f135554d517d09157d0d3d395149050d560821b604082015260600190565b6020808252600e908201526d1154d0d493d5d7d393d517d4d15560921b604082015260600190565b6020808252601a908201527f43414c4c5f484f4f4b5f444154415f4e4f545f414c4c4f574544000000000000604082015260600190565b60208082526011908201527021a0a72a2fa0a62627abafa927aaaa22a960791b604082015260600190565b6020808252600d908201526c1513d2d15397d393d517d1d495609a1b604082015260600190565b6020808252600d908201526c0929cac82989288be929c849eb609b1b604082015260600190565b60208082526018908201527f4f4e4c595f434f554e544552504152545f474154455741590000000000000000604082015260600190565b6020808252600e908201526d1253959053125117d30c97d1d49560921b604082015260600190565b602080825260169082015275130c97d0d3d5539511549410549517d393d517d4d15560521b604082015260600190565b90815260200190565b9283526020830191909152604082015260600190565b60405181810167ffffffffffffffff81118282101715612f4357fe5b604052919050565b600067ffffffffffffffff821115612f5f57fe5b50601f01601f191660200190565b60005b83811015612f88578181015183820152602001612f70565b83811115612f97576000848401525b50505050565b6001600160a01b038116811461079157600080fd5b801515811461079157600080fdfe496e697469616c697a61626c653a20636f6e747261637420697320616c726561647920696e697469616c697a6564536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77a26469706673582212208b012a7dfd44a2bbe8bdcbd17c47507a3fad55d26a64977beb2e9a702ac7ad9864736f6c63430007060033
Deployed Bytecode
0x60806040526004361061020f5760003560e01c80638f438f1711610118578063cac60872116100a0578063d6866ea51161006f578063d6866ea514610595578063ddeb63b5146105aa578063e2fdcc17146105ca578063f77c4791146105df578063fb0e722b146105f45761020f565b8063cac608721461052d578063d2ce7d6514610542578063d426f70014610555578063d653b022146105755761020f565b8063a0c76a96116100e7578063a0c76a9614610480578063a2594d82146104ad578063a7e28d48146104cd578063b83d696e146104ed578063c4d66de81461050d5761020f565b80638f438f171461040b57806391b4ded91461042b57806392eefe9b146104405780639ce7abe5146104605761020f565b806348bde20c1161019b578063721302631161016a578063721302631461038c57806373aea0ae146103ac5780637fee3d43146103c15780638e7c8efe146103e15780638f3112c5146103f65761020f565b806348bde20c146103205780634c381870146103405780635c975abb146103555780636cda3798146103775761020f565b806322ca40a8116101e257806322ca40a8146102a157806324a3d622146102c15780632db09c1c146102e35780632e567b36146102f8578063407395e01461030b5761020f565b8063011e68e31461021457806311dd71291461023657806316c38b3c146102615780631c5b777614610281575b600080fd5b34801561022057600080fd5b5061023461022f36600461254e565b610609565b005b34801561024257600080fd5b5061024b610696565b6040516102589190612f08565b60405180910390f35b34801561026d57600080fd5b5061023461027c366004612790565b61069c565b34801561028d57600080fd5b5061024b61029c36600461281b565b610794565b3480156102ad57600080fd5b506102346102bc36600461254e565b6107ed565b3480156102cd57600080fd5b506102d6610866565b6040516102589190612942565b3480156102ef57600080fd5b506102d6610875565b61023461030636600461260c565b610884565b34801561031757600080fd5b506102d6610c56565b34801561032c57600080fd5b5061023461033b36600461254e565b610c65565b34801561034c57600080fd5b506102d6610cd1565b34801561036157600080fd5b5061036a610ce0565b60405161025891906129f3565b34801561038357600080fd5b5061024b610cf0565b34801561039857600080fd5b506102346103a73660046128eb565b610cf6565b3480156103b857600080fd5b5061024b610d6d565b3480156103cd57600080fd5b506102346103dc3660046128ca565b610d73565b3480156103ed57600080fd5b506102d6610e11565b34801561040257600080fd5b5061024b610e20565b34801561041757600080fd5b5061023461042636600461254e565b610e26565b34801561043757600080fd5b5061024b610f33565b34801561044c57600080fd5b5061023461045b36600461254e565b610f39565b34801561046c57600080fd5b5061023461047b3660046127c8565b610f4a565b34801561048c57600080fd5b506104a061049b36600461268f565b6110a0565b60405161025891906129fe565b3480156104b957600080fd5b506102346104c836600461254e565b611100565b3480156104d957600080fd5b506102d66104e836600461254e565b61121b565b3480156104f957600080fd5b5061036a61050836600461254e565b61125e565b34801561051957600080fd5b5061023461052836600461254e565b611273565b34801561053957600080fd5b5061024b611395565b6104a061055036600461270c565b61139b565b34801561056157600080fd5b5061023461057036600461254e565b611606565b34801561058157600080fd5b506102346105903660046125d4565b6116bc565b3480156105a157600080fd5b506102346117f5565b3480156105b657600080fd5b506102346105c536600461254e565b611901565b3480156105d657600080fd5b506102d661199f565b3480156105eb57600080fd5b506102d66119ae565b34801561060057600080fd5b506102d66119bd565b6106116119cc565b6001600160a01b0381166106405760405162461bcd60e51b815260040161063790612eb0565b60405180910390fd5b604280546001600160a01b0319166001600160a01b0383161790556040517f9a6e2b45041fa2939015ac2bd7e80b890de28d7154ef04b0f52a94fa4e88091d9061068b908390612942565b60405180910390a150565b604b5481565b6004805460408051634fc07d7560e01b815290516001600160a01b0390921692634fc07d75928282019260209290829003018186803b1580156106de57600080fd5b505afa1580156106f2573d6000803e3d6000fd5b505050506040513d602081101561070857600080fd5b50516001600160a01b031633148061072a57506003546001600160a01b031633145b61077b576040805162461bcd60e51b815260206004820152601960248201527f4f6e6c7920476f7665726e6f72206f7220477561726469616e00000000000000604482015290519081900360640190fd5b8061078857610788611a96565b61079181611b36565b50565b6000604a548210156107b85760405162461bcd60e51b815260040161063790612b7e565b6107e56107dc6107d3604a5485611bc790919063ffffffff16565b604b5490611c29565b60495490611c89565b90505b919050565b6107f56119cc565b6001600160a01b03811661081b5760405162461bcd60e51b815260040161063790612cca565b604580546001600160a01b0319166001600160a01b0383161790556040517f75d3e58d9088e31d57a8da4c52196f9d30e8f6fd45543bbe506679e2bef8eaa79061068b908390612942565b6003546001600160a01b031681565b6045546001600160a01b031690565b61088c611ce3565b6043546001600160a01b03166108b45760405162461bcd60e51b815260040161063790612b57565b6045546001600160a01b03166108dc5760405162461bcd60e51b815260040161063790612ed8565b604354604080516373c6754960e11b815290516000926001600160a01b03169163e78cea92916004808301926020929190829003018186803b15801561092157600080fd5b505afa158015610935573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610959919061256a565b9050336001600160a01b038216146109835760405162461bcd60e51b815260040161063790612a6a565b6000816001600160a01b031663ab5d89436040518163ffffffff1660e01b815260040160206040518083038186803b1580156109be57600080fd5b505afa1580156109d2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109f6919061256a565b6001600160a01b03166380648b026040518163ffffffff1660e01b815260040160206040518083038186803b158015610a2e57600080fd5b505afa158015610a42573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a66919061256a565b6045549091506001600160a01b03808316911614610a965760405162461bcd60e51b815260040161063790612e79565b6000610aa0611d36565b9050806001600160a01b0316896001600160a01b031614610ad35760405162461bcd60e51b815260040161063790612e2b565b6046546040516370a0823160e01b81526000916001600160a01b03808516926370a0823192610b06921690600401612942565b60206040518083038186803b158015610b1e57600080fd5b505afa158015610b32573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b569190612833565b905080871115610b7257610b72610b6d8883611bc7565b611d66565b6046546040516323b872dd60e01b81526001600160a01b03848116926323b872dd92610ba892909116908c908c906004016129b6565b602060405180830381600087803b158015610bc257600080fd5b505af1158015610bd6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bfa91906127ac565b506000886001600160a01b03168a6001600160a01b03167f891afe029c75c4f8c5855fc3480598bc5a53739344f6ae575bdb7ea2a79f56b38d8b604051610c429291906129da565b60405180910390a450505050505050505050565b6044546001600160a01b031681565b610c6d6119cc565b6001600160a01b038116610cc8576040805162461bcd60e51b815260206004820152601960248201527f5061757365477561726469616e206d7573742062652073657400000000000000604482015290519081900360640190fd5b61079181611e37565b6042546001600160a01b031681565b6000546301000000900460ff1690565b60015481565b610cfe6119cc565b438110610d1d5760405162461bcd60e51b815260040161063790612c67565b6049839055604b829055604a8190556040517fbfdf0135edba030abcdb9dfcdd3856c401a97acac62e96ba34714ae9cff0ebe690610d6090859085908590612f11565b60405180910390a1505050565b604a5481565b610d7b6119cc565b438110610d9a5760405162461bcd60e51b815260040161063790612c67565b604a548111610dbb5760405162461bcd60e51b815260040161063790612abc565b610dc481610794565b6049819055604a829055604b8390556040517fbfdf0135edba030abcdb9dfcdd3856c401a97acac62e96ba34714ae9cff0ebe691610e059185908590612f11565b60405180910390a15050565b6045546001600160a01b031681565b60485481565b610e2e6119cc565b6001600160a01b038116610e545760405162461bcd60e51b815260040161063790612a11565b6044546001600160a01b0382811691161415610e825760405162461bcd60e51b815260040161063790612e00565b610e8b81611e8b565b610ea75760405162461bcd60e51b815260040161063790612d77565b6001600160a01b03811660009081526047602052604090205460ff1615610ee05760405162461bcd60e51b815260040161063790612c3a565b6001600160a01b03811660009081526047602052604090819020805460ff19166001179055517ff3b329c349ad69ad25f0137ff68c2eaf5ad22fc53cd7a1cfe40a52b19499c1d29061068b908390612942565b60025481565b610f41611e91565b61079181611ef0565b82806001600160a01b031663f851a4406040518163ffffffff1660e01b8152600401602060405180830381600087803b158015610f8657600080fd5b505af1158015610f9a573d6000803e3d6000fd5b505050506040513d6020811015610fb057600080fd5b50516001600160a01b0316331461100e576040805162461bcd60e51b815260206004820152601e60248201527f43616c6c6572206d757374206265207468652070726f78792061646d696e0000604482015290519081900360640190fd5b60405163623faf6160e01b8152602060048201908152602482018490526001600160a01b0386169163623faf619186918691908190604401848480828437600081840152601f19601f8201169050808301925050509350505050600060405180830381600087803b15801561108257600080fd5b505af1158015611096573d6000803e3d6000fd5b5050505050505050565b6060632e567b3660e01b86868686866040516024016110c3959493929190612970565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152905095945050505050565b80806001600160a01b031663f851a4406040518163ffffffff1660e01b8152600401602060405180830381600087803b15801561113c57600080fd5b505af1158015611150573d6000803e3d6000fd5b505050506040513d602081101561116657600080fd5b50516001600160a01b031633146111c4576040805162461bcd60e51b815260206004820152601e60248201527f43616c6c6572206d757374206265207468652070726f78792061646d696e0000604482015290519081900360640190fd5b816001600160a01b03166359fc20bb6040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156111ff57600080fd5b505af1158015611213573d6000803e3d6000fd5b505050505050565b600080611226611d36565b9050806001600160a01b0316836001600160a01b03161461124b5760009150506107e8565b50506042546001600160a01b0316919050565b60476020526000908152604090205460ff1681565b61127b611f98565b6001600160a01b0316336001600160a01b0316146112d6576040805162461bcd60e51b815260206004820152601360248201527227b7363c9034b6b83632b6b2b73a30ba34b7b760691b604482015290519081900360640190fd5b600054610100900460ff16806112ef57506112ef611fbd565b806112fd575060005460ff16155b6113385760405162461bcd60e51b815260040180806020018281038252602e815260200180612fc1602e913960400191505060405180910390fd5b600054610100900460ff16158015611363576000805460ff1961ff0019909116610100171660011790555b61136c82610f41565b6000805463ff000000191663010000001790558015611391576000805461ff00191690555b5050565b60495481565b60606113a5611ce3565b60006113af611d36565b9050866113ce5760405162461bcd60e51b815260040161063790612b2a565b806001600160a01b0316896001600160a01b0316146113ff5760405162461bcd60e51b815260040161063790612e2b565b6001600160a01b0388166114255760405162461bcd60e51b815260040161063790612cfa565b60008060006060806114378989611fce565b80519297509094509150158061146157503360009081526047602052604090205460ff1615156001145b61147d5760405162461bcd60e51b815260040161063790612dc9565b8261149a5760405162461bcd60e51b815260040161063790612c0e565b6114a78e868f8f856110a0565b915050600060405180606001604052808481526020018c81526020018b8152509050856001600160a01b03166323b872dd86604660009054906101000a90046001600160a01b03168f6040518463ffffffff1660e01b815260040161150e939291906129b6565b602060405180830381600087803b15801561152857600080fd5b505af115801561153c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061156091906127ac565b50604354604554611583916001600160a01b039081169116873460008688612067565b9350505050808a6001600160a01b0316836001600160a01b03167fb8910b9960c443aac3240b98585384e3a6f109fbf6969e264c3f183d69aba7e18e8d6040516115ce9291906129da565b60405180910390a4806040516020016115e79190612f08565b6040516020818303038152906040529350505050979650505050505050565b61160e6119cc565b6001600160a01b0381166116345760405162461bcd60e51b815260040161063790612a11565b6001600160a01b03811660009081526047602052604090205460ff1661166c5760405162461bcd60e51b815260040161063790612a93565b6001600160a01b03811660009081526047602052604090819020805460ff19169055517f418f3ae472ec14bb195924385de80a9e9303050c823552568af2adb8388d9d099061068b908390612942565b6116c46119cc565b6001600160a01b0382166116ea5760405162461bcd60e51b815260040161063790612e52565b6001600160a01b0381166117105760405162461bcd60e51b815260040161063790612be3565b6001600160a01b03811660009081526047602052604090205460ff16156117495760405162461bcd60e51b815260040161063790612c93565b61175282611e8b565b61176e5760405162461bcd60e51b815260040161063790612bb3565b61177781611e8b565b6117935760405162461bcd60e51b815260040161063790612af3565b604380546001600160a01b038085166001600160a01b03199283161790925560448054928416929091169190911790556040517fc5f09bf22bb39edf3e4c5f4fd5c4809125836ddc8a0937099d04f53f31eda23d90610e059084908490612956565b61181e6040518060400160405280600881526020016721bab930ba34b7b760c11b815250612092565b61184b6040518060400160405280600c81526020016b22b837b1b426b0b730b3b2b960a11b815250612092565b61187a6040518060400160405280600e81526020016d2932bbb0b93239a6b0b730b3b2b960911b815250612092565b6118a2604051806040016040528060078152602001665374616b696e6760c81b815250612092565b6118cd6040518060400160405280600a81526020016923b930b8342a37b5b2b760b11b815250612092565b6118ff604051806040016040528060118152602001704772617068546f6b656e4761746577617960781b815250612092565b565b6119096119cc565b6001600160a01b03811661192f5760405162461bcd60e51b815260040161063790612d4f565b61193881611e8b565b6119545760405162461bcd60e51b815260040161063790612d77565b604680546001600160a01b0319166001600160a01b0383161790556040517f14229a64f0a7328601813f0f794bb1dbc59363f1ed61c2f957d00517e6140e189061068b908390612942565b6046546001600160a01b031681565b6004546001600160a01b031681565b6043546001600160a01b031681565b6004805460408051634fc07d7560e01b815290516001600160a01b0390921692634fc07d75928282019260209290829003018186803b158015611a0e57600080fd5b505afa158015611a22573d6000803e3d6000fd5b505050506040513d6020811015611a3857600080fd5b50516001600160a01b031633146118ff576040805162461bcd60e51b815260206004820152601860248201527f4f6e6c7920436f6e74726f6c6c657220676f7665726e6f720000000000000000604482015290519081900360640190fd5b6043546001600160a01b0316611abe5760405162461bcd60e51b815260040161063790612b57565b6044546001600160a01b0316611ae65760405162461bcd60e51b815260040161063790612d27565b6045546001600160a01b0316611b0e5760405162461bcd60e51b815260040161063790612ed8565b6046546001600160a01b03166118ff5760405162461bcd60e51b815260040161063790612da1565b600060039054906101000a900460ff1615158115151415611b5657610791565b6000805463ff000000191663010000008315158102919091179182905560ff91041615611b8257426002555b60005460408051630100000090920460ff1615158252517f8fb6c181ee25a520cf3dd6565006ef91229fcfe5a989566c2a3b8c115570cec5916020908290030190a150565b600082821115611c1e576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b508082035b92915050565b600082611c3857506000611c23565b82820282848281611c4557fe5b0414611c825760405162461bcd60e51b8152600401808060200182810382526021815260200180612fef6021913960400191505060405180910390fd5b9392505050565b600082820183811015611c82576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b6000546301000000900460ff16156118ff576040805162461bcd60e51b81526020600482015260116024820152705061757365642028636f6e74726163742960781b604482015290519081900360640190fd5b6000611d617f45fc200c7e4544e457d3c5709bfe0d520442c30bbcbdaede89e8d4a4bbc19247612204565b905090565b611d6f8161229e565b611d8b5760405162461bcd60e51b815260040161063790612a3a565b604854611d989082611c89565b604855611da3611d36565b6046546040516340c10f1960e01b81526001600160a01b03928316926340c10f1992611dd69291169085906004016129da565b600060405180830381600087803b158015611df057600080fd5b505af1158015611e04573d6000803e3d6000fd5b505050507f4f8ca17191c10265804777143e4643b72f8a4c63ad6a973e2ed85532194abf828160405161068b9190612f08565b600380546001600160a01b038381166001600160a01b03198316179283905560405191811692169082907f0613b6ee6a04f0d09f390e4d9318894b9f6ac7fd83897cd8d18896ba579c401e90600090a35050565b3b151590565b6004546001600160a01b031633146118ff576040805162461bcd60e51b815260206004820152601960248201527f43616c6c6572206d75737420626520436f6e74726f6c6c657200000000000000604482015290519081900360640190fd5b6001600160a01b038116611f44576040805162461bcd60e51b815260206004820152601660248201527510dbdb9d1c9bdb1b195c881b5d5cdd081899481cd95d60521b604482015290519081900360640190fd5b600480546001600160a01b0383166001600160a01b0319909116811790915560408051918252517f4ff638452bbf33c012645d18ae6f05515ff5f2d1dfb0cece8cbf018c60903f709181900360200190a150565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6000611fc830611e8b565b15905090565b60445460009081906060908290819083906001600160a01b031633141561200557611ffb87890189612586565b9093509050612042565b33925087878080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509293505050505b80806020019051810190612056919061284b565b939650945091925050509250925092565b60006120868888888888886000015189602001518a604001518a6122be565b98975050505050505050565b6000816040516020018082805190602001908083835b602083106120c75780518252601f1990920191602091820191016120a8565b51815160209384036101000a60001901801990921691161790526040805192909401828103601f1901835280855282519282019290922060048054637bb20d2f60e11b85529084018290529451909750600096506001600160a01b03909416945063f7641a5e93602480840194509192909190829003018186803b15801561214e57600080fd5b505afa158015612162573d6000803e3d6000fd5b505050506040513d602081101561217857600080fd5b50516000838152600560205260409020549091506001600160a01b038083169116146121ff5760008281526005602090815260409182902080546001600160a01b0319166001600160a01b0385169081179091558251908152915184927fd0e7a942b1fc38c411c4f53d153ba14fd24542a6a35ebacd9b6afca1a154e20692908290030190a25b505050565b6000818152600560205260408120546001600160a01b0316806107e5576004805460408051637bb20d2f60e11b8152928301869052516001600160a01b039091169163f7641a5e916024808301926020929190829003018186803b15801561226b57600080fd5b505afa15801561227f573d6000803e3d6000fd5b505050506040513d602081101561229557600080fd5b50519392505050565b60006122a943610794565b6048546122b69084611c89565b111592915050565b6000808a6001600160a01b031663679b6ded898c8a8a8e8f8c8c8c6040518a63ffffffff1660e01b815260040180896001600160a01b03168152602001888152602001878152602001866001600160a01b03168152602001856001600160a01b0316815260200184815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b8381101561236a578181015183820152602001612352565b50505050905090810190601f1680156123975780820380516001836020036101000a031916815260200191505b5099505050505050505050506020604051808303818588803b1580156123bc57600080fd5b505af11580156123d0573d6000803e3d6000fd5b50505050506040513d60208110156123e757600080fd5b81019080805190602001909291905050509050808a6001600160a01b03168a6001600160a01b03167fc1d1490cf25c3b40d600dfb27c7680340ed1ab901b7e8f3551280968a3b372b0866040518080602001828103825283818151815260200191508051906020019080838360005b8381101561246e578181015183820152602001612456565b50505050905090810190601f16801561249b5780820380516001836020036101000a031916815260200191505b509250505060405180910390a49a9950505050505050505050565b60008083601f8401126124c7578182fd5b50813567ffffffffffffffff8111156124de578182fd5b6020830191508360208285010111156124f657600080fd5b9250929050565b600082601f83011261250d578081fd5b813561252061251b82612f4b565b612f27565b818152846020838601011115612534578283fd5b816020850160208301379081016020019190915292915050565b60006020828403121561255f578081fd5b8135611c8281612f9d565b60006020828403121561257b578081fd5b8151611c8281612f9d565b60008060408385031215612598578081fd5b82356125a381612f9d565b9150602083013567ffffffffffffffff8111156125be578182fd5b6125ca858286016124fd565b9150509250929050565b600080604083850312156125e6578182fd5b82356125f181612f9d565b9150602083013561260181612f9d565b809150509250929050565b60008060008060008060a08789031215612624578182fd5b863561262f81612f9d565b9550602087013561263f81612f9d565b9450604087013561264f81612f9d565b935060608701359250608087013567ffffffffffffffff811115612671578283fd5b61267d89828a016124b6565b979a9699509497509295939492505050565b600080600080600060a086880312156126a6578081fd5b85356126b181612f9d565b945060208601356126c181612f9d565b935060408601356126d181612f9d565b925060608601359150608086013567ffffffffffffffff8111156126f3578182fd5b6126ff888289016124fd565b9150509295509295909350565b600080600080600080600060c0888a031215612726578081fd5b873561273181612f9d565b9650602088013561274181612f9d565b955060408801359450606088013593506080880135925060a088013567ffffffffffffffff811115612771578182fd5b61277d8a828b016124b6565b989b979a50959850939692959293505050565b6000602082840312156127a1578081fd5b8135611c8281612fb2565b6000602082840312156127bd578081fd5b8151611c8281612fb2565b6000806000604084860312156127dc578081fd5b83356127e781612f9d565b9250602084013567ffffffffffffffff811115612802578182fd5b61280e868287016124b6565b9497909650939450505050565b60006020828403121561282c578081fd5b5035919050565b600060208284031215612844578081fd5b5051919050565b6000806040838503121561285d578182fd5b82519150602083015167ffffffffffffffff81111561287a578182fd5b8301601f8101851361288a578182fd5b805161289861251b82612f4b565b8181528660208385010111156128ac578384fd5b6128bd826020830160208601612f6d565b8093505050509250929050565b600080604083850312156128dc578182fd5b50508035926020909101359150565b6000806000606084860312156128ff578081fd5b505081359360208301359350604090920135919050565b6000815180845261292e816020860160208601612f6d565b601f01601f19169290920160200192915050565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b6001600160a01b0386811682528581166020830152841660408201526060810183905260a0608082018190526000906129ab90830184612916565b979650505050505050565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b03929092168252602082015260400190565b901515815260200190565b600060208252611c826020830184612916565b6020808252600f908201526e494e56414c49445f4144445245535360881b604082015260600190565b6020808252601690820152751253959053125117d30c97d352539517d05353d5539560521b604082015260600190565b6020808252600f908201526e4e4f545f46524f4d5f42524944474560881b604082015260600190565b6020808252600f908201526e1393d517d0531313d5d31254d51151608a1b604082015260600190565b6020808252601a908201527f424c4f434b5f4d5553545f42455f494e4352454d454e54494e47000000000000604082015260600190565b60208082526017908201527f524f555445525f4d5553545f42455f434f4e5452414354000000000000000000604082015260600190565b6020808252601390820152721253959053125117d6915493d7d05353d55395606a1b604082015260600190565b6020808252600d908201526c12539093d617d393d517d4d155609a1b604082015260600190565b6020808252818101527f494e56414c49445f424c4f434b5f464f525f4d494e545f414c4c4f57414e4345604082015260600190565b60208082526016908201527512539093d617d35554d517d09157d0d3d395149050d560521b604082015260600190565b60208082526011908201527024a72b20a624a22fa618afa927aaaa22a960791b604082015260600190565b6020808252601290820152711393d7d4d550935254d4d253d397d0d3d4d560721b604082015260600190565b6020808252601390820152721053149150511657d0531313d5d31254d51151606a1b604082015260600190565b602080825260129082015271109313d0d2d7d35554d517d09157d41054d560721b604082015260600190565b6020808252601a908201527f524f555445525f43414e545f42455f414c4c4f574c4953544544000000000000604082015260600190565b6020808252601690820152751253959053125117d30c97d0d3d5539511549410549560521b604082015260600190565b60208082526013908201527224a72b20a624a22fa222a9aa24a720aa24a7a760691b604082015260600190565b6020808252600e908201526d1493d555115497d393d517d4d15560921b604082015260600190565b6020808252600e908201526d494e56414c49445f455343524f5760901b604082015260600190565b60208082526010908201526f135554d517d09157d0d3d395149050d560821b604082015260600190565b6020808252600e908201526d1154d0d493d5d7d393d517d4d15560921b604082015260600190565b6020808252601a908201527f43414c4c5f484f4f4b5f444154415f4e4f545f414c4c4f574544000000000000604082015260600190565b60208082526011908201527021a0a72a2fa0a62627abafa927aaaa22a960791b604082015260600190565b6020808252600d908201526c1513d2d15397d393d517d1d495609a1b604082015260600190565b6020808252600d908201526c0929cac82989288be929c849eb609b1b604082015260600190565b60208082526018908201527f4f4e4c595f434f554e544552504152545f474154455741590000000000000000604082015260600190565b6020808252600e908201526d1253959053125117d30c97d1d49560921b604082015260600190565b602080825260169082015275130c97d0d3d5539511549410549517d393d517d4d15560521b604082015260600190565b90815260200190565b9283526020830191909152604082015260600190565b60405181810167ffffffffffffffff81118282101715612f4357fe5b604052919050565b600067ffffffffffffffff821115612f5f57fe5b50601f01601f191660200190565b60005b83811015612f88578181015183820152602001612f70565b83811115612f97576000848401525b50505050565b6001600160a01b038116811461079157600080fd5b801515811461079157600080fdfe496e697469616c697a61626c653a20636f6e747261637420697320616c726561647920696e697469616c697a6564536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77a26469706673582212208b012a7dfd44a2bbe8bdcbd17c47507a3fad55d26a64977beb2e9a702ac7ad9864736f6c63430007060033
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 34 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
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.