Overview
ETH Balance
0 ETH
Eth Value
$0.00Token Holdings
More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 2,792 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Update Flip Supp... | 21247945 | 3 hrs ago | IN | 0 ETH | 0.0030265 | ||||
Register Redempt... | 21247734 | 3 hrs ago | IN | 0 ETH | 0.00145729 | ||||
Fund State Chain... | 21247708 | 4 hrs ago | IN | 0 ETH | 0.000552 | ||||
Fund State Chain... | 21247681 | 4 hrs ago | IN | 0 ETH | 0.00059839 | ||||
Fund State Chain... | 21247565 | 4 hrs ago | IN | 0 ETH | 0.00067725 | ||||
Fund State Chain... | 21244674 | 14 hrs ago | IN | 0 ETH | 0.00063772 | ||||
Update Flip Supp... | 21240781 | 27 hrs ago | IN | 0 ETH | 0.00099126 | ||||
Fund State Chain... | 21238030 | 36 hrs ago | IN | 0 ETH | 0.00082913 | ||||
Register Redempt... | 21237439 | 38 hrs ago | IN | 0 ETH | 0.00235501 | ||||
Register Redempt... | 21237427 | 38 hrs ago | IN | 0 ETH | 0.00287113 | ||||
Register Redempt... | 21237426 | 38 hrs ago | IN | 0 ETH | 0.00259135 | ||||
Register Redempt... | 21237422 | 38 hrs ago | IN | 0 ETH | 0.0026112 | ||||
Register Redempt... | 21237420 | 38 hrs ago | IN | 0 ETH | 0.00298573 | ||||
Register Redempt... | 21237416 | 38 hrs ago | IN | 0 ETH | 0.00281197 | ||||
Register Redempt... | 21237382 | 38 hrs ago | IN | 0 ETH | 0.0027948 | ||||
Register Redempt... | 21237369 | 38 hrs ago | IN | 0 ETH | 0.00238473 | ||||
Register Redempt... | 21237366 | 38 hrs ago | IN | 0 ETH | 0.00255335 | ||||
Register Redempt... | 21235237 | 45 hrs ago | IN | 0 ETH | 0.00148537 | ||||
Register Redempt... | 21235236 | 45 hrs ago | IN | 0 ETH | 0.00148988 | ||||
Register Redempt... | 21235235 | 45 hrs ago | IN | 0 ETH | 0.00135137 | ||||
Register Redempt... | 21235235 | 45 hrs ago | IN | 0 ETH | 0.00135137 | ||||
Register Redempt... | 21235235 | 45 hrs ago | IN | 0 ETH | 0.00138386 | ||||
Register Redempt... | 21235234 | 45 hrs ago | IN | 0 ETH | 0.00138125 | ||||
Register Redempt... | 21234888 | 46 hrs ago | IN | 0 ETH | 0.00123518 | ||||
Update Flip Supp... | 21233617 | 2 days ago | IN | 0 ETH | 0.00097809 |
Latest 1 internal transaction
Advanced mode:
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
18277081 | 415 days ago | Contract Creation | 0 ETH |
Loading...
Loading
Contract Name:
StateChainGateway
Compiler Version
v0.8.20+commit.a1b79de6
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "IERC20.sol"; import "IStateChainGateway.sol"; import "IKeyManager.sol"; import "IFlipIssuer.sol"; import "IFLIP.sol"; import "AggKeyNonceConsumer.sol"; import "GovernanceCommunityGuarded.sol"; /** * @title State Chain Gateway contract * @notice Manages the funding and redemption FLIP from/to stateChain accounts. * Accounts on the FLIP state chain basically have full control * of FLIP leaving the contract. FLIP can be added to the StateChain * account via `fundStateChainAccount` with their stateChain nodeID. * * This contract also handles the minting and burning of FLIP after the * initial supply is minted during FLIP's creation. At any time, a * valid aggragate signature can be submitted to the contract which * updates the total supply by minting or burning the necessary FLIP. */ contract StateChainGateway is IFlipIssuer, IStateChainGateway, AggKeyNonceConsumer, GovernanceCommunityGuarded { /// @dev The FLIP token address. To be set only once after deployment via setFlip. // solhint-disable-next-line var-name-mixedcase IFLIP private _FLIP; /// @dev The minimum amount of FLIP needed to fund an account, to prevent spamming uint256 private _minFunding; /// @dev Holding pending redemptions for the 48h withdrawal delay mapping(bytes32 => Redemption) private _pendingRedemptions; /// @dev Time after registerRedemption required to wait before call to executeRedemption // solhint-disable-next-line var-name-mixedcase uint48 public immutable REDEMPTION_DELAY; /// @dev The last block number in which the State Chain updated the totalSupply uint256 private _lastSupplyUpdateBlockNum = 0; // Defined in IStateChainGateway, just here for convenience // struct Redemption { // uint amount; // address redeemAddress; // // 48 so that 160 (from redeemAddress) + 48 + 48 is 256 they can all be packed // // into a single 256 bit slot // uint48 startTime; // uint48 expiryTime; // address executor; // } constructor( IKeyManager keyManager, uint256 minFunding, uint48 redemptionDelay ) AggKeyNonceConsumer(keyManager) nzUint(redemptionDelay) { _minFunding = minFunding; REDEMPTION_DELAY = redemptionDelay; } /// @dev Get the governor address from the KeyManager. This is called by the onlyGovernor /// modifier in the GovernanceCommunityGuarded. This logic can't be moved to the /// GovernanceCommunityGuarded since it requires a reference to the KeyManager. function _getGovernor() internal view override returns (address) { return getKeyManager().getGovernanceKey(); } /// @dev Get the community key from the KeyManager. This is called by the isCommunityKey /// modifier in the GovernanceCommunityGuarded. This logic can't be moved to the /// GovernanceCommunityGuarded since it requires a reference to the KeyManager. function _getCommunityKey() internal view override returns (address) { return getKeyManager().getCommunityKey(); } /** * @notice Get the FLIP token address * @dev This function and it's return value will be checked when updating the FLIP issuer. * Do not remove nor modify this function in future versions of this contract. * @return The address of FLIP */ function getFLIP() external view override returns (IFLIP) { return _FLIP; } /// @dev Ensure that a new keyManager has the getGovernanceKey() and getCommunityKey() /// functions implemented. These are functions required for this contract to /// to at least be able to use the emergency mechanism. function _checkUpdateKeyManager(IKeyManager keyManager, bool omitChecks) internal view override { address newGovKey = keyManager.getGovernanceKey(); address newCommKey = keyManager.getCommunityKey(); if (!omitChecks) { // Ensure that the keys are the same require(newGovKey == _getGovernor() && newCommKey == _getCommunityKey()); Key memory newAggKey = keyManager.getAggregateKey(); Key memory currentAggKey = getKeyManager().getAggregateKey(); require( newAggKey.pubKeyX == currentAggKey.pubKeyX && newAggKey.pubKeyYParity == currentAggKey.pubKeyYParity ); } else { // Check that the addresses have been initialized require(newGovKey != address(0) && newCommKey != address(0)); } } ////////////////////////////////////////////////////////////// // // // State-changing functions // // // ////////////////////////////////////////////////////////////// /** * @notice Sets the FLIP address after initialization. We can't do this in the constructor * because FLIP contract requires this contract's address on deployment for minting. * First this contract is deployed, then the FLIP contract and finally setFLIP * should be called. Deployed via DeployerContract.sol so it can't be frontrun. * The FLIP address can only be set once. * @param flip FLIP token address */ function setFlip(IFLIP flip) external override nzAddr(address(flip)) { require(address(_FLIP) == address(0), "Gateway: Flip address already set"); _FLIP = flip; emit FLIPSet(address(flip)); } /** * @notice Add FLIP funds to a StateChain account identified with a nodeID * @dev Requires the funder to have called `approve` in FLIP * @param amount The amount of FLIP tokens * @param nodeID The nodeID of the account to fund */ function fundStateChainAccount(bytes32 nodeID, uint256 amount) external override nzBytes32(nodeID) { IFLIP flip = _FLIP; require(address(flip) != address(0), "Gateway: Flip not set"); require(amount >= _minFunding, "Gateway: not enough funds"); // Assumption of set token allowance by the user flip.transferFrom(msg.sender, address(this), amount); emit Funded(nodeID, amount, msg.sender); } /** * @notice Redeem FLIP from the StateChain. The State Chain will determine the amount * that can be redeemed, but a basic calculation for a validator would be: * amount redeemable = stake + rewards - penalties. * @param sigData Struct containing the signature data over the message * to verify, signed by the aggregate key. * @param nodeID The nodeID of the account redeeming the FLIP * @param amount The amount of funds to be locked up * @param redeemAddress The redeemAddress who will receive the FLIP * @param expiryTime The last valid timestamp that can execute this redemption (uint48) * @param executor The address that can execute the redemption (zero address if anyone) */ function registerRedemption( SigData calldata sigData, bytes32 nodeID, uint256 amount, address redeemAddress, uint48 expiryTime, address executor ) external override onlyNotSuspended nzBytes32(nodeID) nzUint(amount) nzAddr(redeemAddress) consumesKeyNonce( sigData, keccak256(abi.encode(this.registerRedemption.selector, nodeID, amount, redeemAddress, expiryTime, executor)) ) { require( // Must be fresh or have been executed & deleted, or past the expiry block.timestamp > uint256(_pendingRedemptions[nodeID].expiryTime), "Gateway: a pending redemption exists" ); uint48 startTime = uint48(block.timestamp) + REDEMPTION_DELAY; require(expiryTime > startTime, "Gateway: expiry time too soon"); _pendingRedemptions[nodeID] = Redemption(amount, redeemAddress, startTime, expiryTime, executor); emit RedemptionRegistered(nodeID, amount, redeemAddress, startTime, expiryTime, executor); } /** * @notice Execute a pending redemption to get back funds. Cannot execute a pending * redemption before 48h have passed after registering it, or after the specified * expiry time * @dev No need for nzUint(nodeID) since that is handled by `redemption.expiryTime > 0` * @param nodeID The nodeID of the funder */ function executeRedemption(bytes32 nodeID) external override onlyNotSuspended returns (address, uint256) { Redemption memory redemption = _pendingRedemptions[nodeID]; require( block.timestamp >= redemption.startTime && redemption.expiryTime > 0, "Gateway: early or already execd" ); // Housekeeping delete _pendingRedemptions[nodeID]; if (block.timestamp <= redemption.expiryTime) { if (redemption.executor != address(0)) { require(msg.sender == redemption.executor, "Gateway: not executor"); } emit RedemptionExecuted(nodeID, redemption.amount); // Send the tokens _FLIP.transfer(redemption.redeemAddress, redemption.amount); return (redemption.redeemAddress, redemption.amount); } else { emit RedemptionExpired(nodeID, redemption.amount); return (redemption.redeemAddress, 0); } } /** * @notice Compares a given new FLIP supply against the old supply and mints or burns * FLIP tokens from this contract as appropriate. * It requires a message signed by the aggregate key. * @dev Hardcoded to only mint and burn FLIP tokens to/from this contract. * @param sigData Struct containing the signature data over the message * to verify, signed by the aggregate key. * @param newTotalSupply new total supply of FLIP * @param stateChainBlockNumber State Chain block number for the new total supply */ function updateFlipSupply( SigData calldata sigData, uint256 newTotalSupply, uint256 stateChainBlockNumber ) external override onlyNotSuspended nzUint(newTotalSupply) consumesKeyNonce( sigData, keccak256(abi.encode(this.updateFlipSupply.selector, newTotalSupply, stateChainBlockNumber)) ) { require(stateChainBlockNumber > _lastSupplyUpdateBlockNum, "Gateway: old FLIP supply update"); _lastSupplyUpdateBlockNum = stateChainBlockNumber; IFLIP flip = _FLIP; uint256 oldSupply = flip.totalSupply(); if (newTotalSupply < oldSupply) { uint256 amount = oldSupply - newTotalSupply; flip.burn(address(this), amount); } else if (newTotalSupply > oldSupply) { uint256 amount = newTotalSupply - oldSupply; flip.mint(address(this), amount); } emit FlipSupplyUpdated(oldSupply, newTotalSupply, stateChainBlockNumber); } /** * @notice Updates the address that is allowed to issue FLIP tokens. This will be used when this * contract needs an upgrade. A new contract will be deployed and all the FLIP will be * transferred to it via the redemption process. Finally the right to issue FLIP will be transferred. * @dev The new issuer must be a contract and, in a standard upgrade, it must have the reference FLIP address. * In a special case where the check is omitted, the new issuer must be a contract, never an EOA. * @param sigData Struct containing the signature data over the message * to verify, signed by the aggregate key. * @param newIssuer New contract that will issue FLIP tokens. * @param omitChecks Allow the omission of the extra checks in a special case */ function updateFlipIssuer( SigData calldata sigData, address newIssuer, bool omitChecks ) external override onlyNotSuspended nzAddr(newIssuer) consumesKeyNonce(sigData, keccak256(abi.encode(this.updateFlipIssuer.selector, newIssuer, omitChecks))) { if (!omitChecks) { require(IFlipIssuer(newIssuer).getFLIP() == _FLIP, "Gateway: wrong FLIP ref"); } else { require(newIssuer.code.length > 0); } _FLIP.updateIssuer(newIssuer); } /** * @notice Set the minimum amount of funds needed for `fundStateChainAccount` to be able * to be called. Used to prevent spamming of funding. * @param newMinFunding The new minimum funding amount */ function setMinFunding(uint256 newMinFunding) external override nzUint(newMinFunding) onlyGovernor { emit MinFundingChanged(_minFunding, newMinFunding); _minFunding = newMinFunding; } /** * @notice Withdraw all FLIP to governance address in case of emergency. This withdrawal needs * to be approved by the Community, it is a last resort. Used to rectify an emergency. * Transfer the issuance to the governance address if this contract is the issuer. */ function govWithdraw() external override onlyGovernor onlyCommunityGuardDisabled onlySuspended { IFLIP flip = _FLIP; uint256 amount = flip.balanceOf(address(this)); // Could use msg.sender or getGovernor() but hardcoding the get call just for extra safety address governor = getKeyManager().getGovernanceKey(); flip.transfer(governor, amount); emit GovernanceWithdrawal(governor, amount); // Check issuer to ensure this doesn't revert if (flip.getIssuer() == address(this)) { flip.updateIssuer(governor); } } /** * @notice Update the FLIP Issuer address with the governance address in case of emergency. * This needs to be approved by the Community, it is a last resort. Used to rectify * an emergency. */ function govUpdateFlipIssuer() external override onlyGovernor onlyCommunityGuardDisabled onlySuspended { address governor = getKeyManager().getGovernanceKey(); _FLIP.updateIssuer(governor); } ////////////////////////////////////////////////////////////// // // // Non-state-changing functions // // // ////////////////////////////////////////////////////////////// /** * @notice Get the minimum amount of funds that's required for funding * an account on the StateChain. * @return The minimum amount (uint) */ function getMinimumFunding() external view override returns (uint256) { return _minFunding; } /** * @notice Get the pending redemption for the input nodeID. If there was never * a pending redemption for this nodeID, or it has already been executed * (and therefore deleted), it'll return (0, 0x00..., 0, 0) * @param nodeID The nodeID which has a pending redemption * @return The redemption (Redemption struct) */ function getPendingRedemption(bytes32 nodeID) external view override returns (Redemption memory) { return _pendingRedemptions[nodeID]; } /** * @notice Get the last state chain block number of the last supply update * @return The state chain block number of the last supply update */ function getLastSupplyUpdateBlockNumber() external view override returns (uint256) { return _lastSupplyUpdateBlockNum; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 amount ) external returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "IFLIP.sol"; import "IAggKeyNonceConsumer.sol"; import "IGovernanceCommunityGuarded.sol"; import "IFlipIssuer.sol"; /** * @title StateChainGateway interface */ interface IStateChainGateway is IGovernanceCommunityGuarded, IFlipIssuer, IAggKeyNonceConsumer { event Funded(bytes32 indexed nodeID, uint256 amount, address funder); event RedemptionRegistered( bytes32 indexed nodeID, uint256 amount, address indexed redeemAddress, uint48 startTime, uint48 expiryTime, address executor ); event RedemptionExecuted(bytes32 indexed nodeID, uint256 amount); event RedemptionExpired(bytes32 indexed nodeID, uint256 amount); event MinFundingChanged(uint256 oldMinFunding, uint256 newMinFunding); event GovernanceWithdrawal(address to, uint256 amount); event FLIPSet(address flip); event FlipSupplyUpdated(uint256 oldSupply, uint256 newSupply, uint256 stateChainBlockNumber); struct Redemption { uint256 amount; address redeemAddress; // 48 so that 160 (from redeemAddress) + 48 + 48 is 256 they can all be packed // into a single 256 bit slot uint48 startTime; uint48 expiryTime; address executor; } /** * @notice Sets the FLIP address after initialization. We can't do this in the constructor * because FLIP contract requires this contract's address on deployment for minting. * First this contract is deployed, then the FLIP contract and finally setFLIP * should be called. OnlyDeployer modifer for added security since tokens will be * minted to this contract before calling setFLIP. * @param flip FLIP token address */ function setFlip(IFLIP flip) external; /** * @notice Add FLIP funds to a StateChain account identified with a nodeID * @dev Requires the funder to have called `approve` in FLIP * @param amount The amount of FLIP tokens * @param nodeID The nodeID of the account to fund */ function fundStateChainAccount(bytes32 nodeID, uint256 amount) external; /** * @notice Redeem FLIP from the StateChain. The State Chain will determine the amount * that can be redeemed, but a basic calculation for a validator would be: * amount redeemable = stake + rewards - penalties. * @param sigData Struct containing the signature data over the message * to verify, signed by the aggregate key. * @param nodeID The nodeID of the account redeeming the FLIP * @param amount The amount of funds to be locked up * @param redeemAddress The redeemAddress who will receive the FLIP * @param expiryTime The last valid timestamp that can execute this redemption (uint48) */ function registerRedemption( SigData calldata sigData, bytes32 nodeID, uint256 amount, address redeemAddress, uint48 expiryTime, address executor ) external; /** * @notice Execute a pending redemption to get back funds. Cannot execute a pending * redemption before 48h have passed after registering it, or after the specified * expiry time * @dev No need for nzUint(nodeID) since that is handled by `redemption.expiryTime > 0` * @param nodeID The nodeID of the account redeeming the FLIP * @return The address that received the FLIP and the amount */ function executeRedemption(bytes32 nodeID) external returns (address, uint256); /** * @notice Compares a given new FLIP supply against the old supply and mints or burns * FLIP tokens from this contract as appropriate. * It requires a message signed by the aggregate key. * @param sigData Struct containing the signature data over the message * to verify, signed by the aggregate key. * @param newTotalSupply new total supply of FLIP * @param stateChainBlockNumber State Chain block number for the new total supply */ function updateFlipSupply(SigData calldata sigData, uint256 newTotalSupply, uint256 stateChainBlockNumber) external; /** * @notice Updates the address that is allowed to issue FLIP tokens. This will be used when this * contract needs an upgrade. A new contract will be deployed and all the FLIP will be * transferred to it via the redemption process. Finally the right to issue FLIP will be transferred. * @param sigData Struct containing the signature data over the message * to verify, signed by the aggregate key. * @param newIssuer New contract that will issue FLIP tokens. * @param omitChecks Allow the omission of the extra checks in a special case */ function updateFlipIssuer(SigData calldata sigData, address newIssuer, bool omitChecks) external; /** * @notice Set the minimum amount of funds needed for `fundStateChainAccount` to be able * to be called. Used to prevent spamming of funding. * @param newMinFunding The new minimum funding amount */ function setMinFunding(uint256 newMinFunding) external; /** * @notice Withdraw all FLIP to governance address in case of emergency. This withdrawal needs * to be approved by the Community, it is a last resort. Used to rectify an emergency. * The governance address is also updated as the issuer of FLIP. */ function govWithdraw() external; /** * @notice Update the FLIP Issuer address with the governance address in case of emergency. * This needs to be approved by the Community, it is a last resort. Used to rectify * an emergency. */ function govUpdateFlipIssuer() external; ////////////////////////////////////////////////////////////// // // // Non-state-changing functions // // // ////////////////////////////////////////////////////////////// /** * @notice Get the minimum amount of funds that's required for funding * an account on the StateChain. * @return The minimum amount (uint) */ function getMinimumFunding() external view returns (uint256); /** * @notice Get the pending redemption for the input nodeID. If there was never * a pending redemption for this nodeID, or it has already been executed * (and therefore deleted), it'll return (0, 0x00..., 0, 0) * @param nodeID The nodeID which has a pending redemption * @return The redemption (Redemption struct) */ function getPendingRedemption(bytes32 nodeID) external view returns (Redemption memory); /** * @notice Get the last state chain block number that the supply was updated at * @return The state chain block number of the last update */ function getLastSupplyUpdateBlockNumber() external view returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "IERC20.sol"; /** * @title FLIP interface for the FLIP utility token */ interface IFLIP is IERC20 { event IssuerUpdated(address oldIssuer, address newIssuer); ////////////////////////////////////////////////////////////// // // // State-changing functions // // // ////////////////////////////////////////////////////////////// function mint(address account, uint amount) external; function burn(address account, uint amount) external; function updateIssuer(address newIssuer) external; ////////////////////////////////////////////////////////////// // // // Non-state-changing functions // // // ////////////////////////////////////////////////////////////// function getIssuer() external view returns (address); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "IShared.sol"; import "IKeyManager.sol"; /** * @title AggKeyNonceConsumer interface */ interface IAggKeyNonceConsumer is IShared { event UpdatedKeyManager(address keyManager); ////////////////////////////////////////////////////////////// // // // State-changing functions // // // ////////////////////////////////////////////////////////////// /** * @notice Update KeyManager reference. Used if KeyManager contract is updated * @param sigData Struct containing the signature data over the message * to verify, signed by the aggregate key. * @param keyManager New KeyManager's address * @param omitChecks Allow the omission of the extra checks in a special case */ function updateKeyManager(SigData calldata sigData, IKeyManager keyManager, bool omitChecks) external; ////////////////////////////////////////////////////////////// // // // Getters // // // ////////////////////////////////////////////////////////////// /** * @notice Get the KeyManager address/interface that's used to validate sigs * @return The KeyManager (IKeyManager) */ function getKeyManager() external view returns (IKeyManager); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "IERC20.sol"; /** * @title Shared interface * @notice Holds structs needed by other interfaces */ interface IShared { /** * @dev SchnorrSECP256K1 requires that each key has a public key part (x coordinate), * a parity for the y coordinate (0 if the y ordinate of the public key is even, 1 * if it's odd) */ struct Key { uint256 pubKeyX; uint8 pubKeyYParity; } /** * @dev Contains a signature and the nonce used to create it. Also the recovered address * to check that the signature is valid */ struct SigData { uint256 sig; uint256 nonce; address kTimesGAddress; } /** * @param token The address of the token to be transferred * @param recipient The address of the recipient of the transfer * @param amount The amount to transfer, in wei (uint) */ struct TransferParams { address token; address payable recipient; uint256 amount; } /** * @param swapID The unique identifier for this swap (bytes32), used for create2 * @param token The token to be transferred */ struct DeployFetchParams { bytes32 swapID; address token; } /** * @param fetchContract The address of the deployed Deposit contract * @param token The token to be transferred */ struct FetchParams { address payable fetchContract; address token; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "IShared.sol"; /** * @title KeyManager interface * @notice The interface for functions KeyManager implements */ interface IKeyManager is IShared { event AggKeySetByAggKey(Key oldAggKey, Key newAggKey); event AggKeySetByGovKey(Key oldAggKey, Key newAggKey); event GovKeySetByAggKey(address oldGovKey, address newGovKey); event GovKeySetByGovKey(address oldGovKey, address newGovKey); event CommKeySetByAggKey(address oldCommKey, address newCommKey); event CommKeySetByCommKey(address oldCommKey, address newCommKey); event SignatureAccepted(SigData sigData, address signer); event GovernanceAction(bytes32 message); ////////////////////////////////////////////////////////////// // // // State-changing functions // // // ////////////////////////////////////////////////////////////// function consumeKeyNonce(SigData memory sigData, bytes32 contractMsgHash) external; function setAggKeyWithAggKey(SigData memory sigData, Key memory newAggKey) external; function setAggKeyWithGovKey(Key memory newAggKey) external; function setGovKeyWithAggKey(SigData calldata sigData, address newGovKey) external; function setGovKeyWithGovKey(address newGovKey) external; function setCommKeyWithAggKey(SigData calldata sigData, address newCommKey) external; function setCommKeyWithCommKey(address newCommKey) external; function govAction(bytes32 message) external; ////////////////////////////////////////////////////////////// // // // Non-state-changing functions // // // ////////////////////////////////////////////////////////////// function getAggregateKey() external view returns (Key memory); function getGovernanceKey() external view returns (address); function getCommunityKey() external view returns (address); function isNonceUsedByAggKey(uint256 nonce) external view returns (bool); function getLastValidateTime() external view returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "IShared.sol"; /** * @title GovernanceCommunityGuarded interface */ interface IGovernanceCommunityGuarded is IShared { event CommunityGuardDisabled(bool communityGuardDisabled); event Suspended(bool suspended); ////////////////////////////////////////////////////////////// // // // State-changing functions // // // ////////////////////////////////////////////////////////////// /** * @notice Enable Community Guard */ function enableCommunityGuard() external; /** * @notice Disable Community Guard */ function disableCommunityGuard() external; /** * @notice Can be used to suspend contract execution - only executable by * governance and only to be used in case of emergency. */ function suspend() external; /** * @notice Resume contract execution */ function resume() external; ////////////////////////////////////////////////////////////// // // // Getters // // // ////////////////////////////////////////////////////////////// /** * @notice Get the Community Key * @return The CommunityKey */ function getCommunityKey() external view returns (address); /** * @notice Get the Community Guard state * @return The Community Guard state */ function getCommunityGuardDisabled() external view returns (bool); /** * @notice Get suspended state * @return The suspended state */ function getSuspendedState() external view returns (bool); /** * @notice Get governor address * @return The governor address */ function getGovernor() external view returns (address); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "IFLIP.sol"; /** * @title Flip Issuer interface * @notice This interface is required when updating the FLIP issuer. * Additionally, any contract inheriting this should implement the * mint and burn capabilities to interact with the FLIP contract. */ interface IFlipIssuer { /** * @notice Get the FLIP token address * @return The address of FLIP */ function getFLIP() external view returns (IFLIP); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "IKeyManager.sol"; import "IAggKeyNonceConsumer.sol"; import "Shared.sol"; /** * @title AggKeyNonceConsumer contract * @notice Manages the reference to the KeyManager contract. The address * is set in the constructor and can only be updated with a valid * signature validated by the current KeyManager contract. This shall * be done if the KeyManager contract is updated. */ abstract contract AggKeyNonceConsumer is Shared, IAggKeyNonceConsumer { /// @dev The KeyManager used to checks sigs used in functions here IKeyManager private _keyManager; constructor(IKeyManager keyManager) nzAddr(address(keyManager)) { _keyManager = keyManager; } ////////////////////////////////////////////////////////////// // // // State-changing functions // // // ////////////////////////////////////////////////////////////// /** * @notice Update KeyManager reference. Used if KeyManager contract is updated * @param sigData Struct containing the signature data over the message * to verify, signed by the aggregate key. * @param keyManager New KeyManager's address * @param omitChecks Allow the omission of the extra checks in a special case */ function updateKeyManager( SigData calldata sigData, IKeyManager keyManager, bool omitChecks ) external override nzAddr(address(keyManager)) consumesKeyNonce(sigData, keccak256(abi.encode(this.updateKeyManager.selector, keyManager, omitChecks))) { // Check that the new KeyManager is a contract require(address(keyManager).code.length > 0); // Allow the child to check compatibility with the new KeyManager _checkUpdateKeyManager(keyManager, omitChecks); _keyManager = keyManager; emit UpdatedKeyManager(address(keyManager)); } /// @dev This will be called when upgrading to a new KeyManager. This allows the child's contract /// to check its compatibility with the new KeyManager. This is to prevent the contract from // getting bricked. There is no good way to enforce the implementation of consumeKeyNonce(). function _checkUpdateKeyManager(IKeyManager keyManager, bool omitChecks) internal view virtual; ////////////////////////////////////////////////////////////// // // // Getters // // // ////////////////////////////////////////////////////////////// /** * @notice Get the KeyManager address/interface that's used to validate sigs * @return The KeyManager (IKeyManager) */ function getKeyManager() public view override returns (IKeyManager) { return _keyManager; } ////////////////////////////////////////////////////////////// // // // Modifiers // // // ////////////////////////////////////////////////////////////// /// @dev Calls consumeKeyNonce in _keyManager modifier consumesKeyNonce(SigData calldata sigData, bytes32 contractMsgHash) { getKeyManager().consumeKeyNonce(sigData, contractMsgHash); _; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "IShared.sol"; /** * @title Shared contract * @notice Holds constants and modifiers that are used in multiple contracts * @dev It would be nice if this could be a library, but modifiers can't be exported :( */ abstract contract Shared is IShared { /// @dev The address used to indicate whether transfer should send native or a token address internal constant _NATIVE_ADDR = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE; address internal constant _ZERO_ADDR = address(0); bytes32 internal constant _NULL = ""; uint256 internal constant _E_18 = 1e18; /// @dev Checks that a uint isn't zero/empty modifier nzUint(uint256 u) { require(u != 0, "Shared: uint input is empty"); _; } /// @dev Checks that an address isn't zero/empty modifier nzAddr(address a) { require(a != _ZERO_ADDR, "Shared: address input is empty"); _; } /// @dev Checks that a bytes32 isn't zero/empty modifier nzBytes32(bytes32 b) { require(b != _NULL, "Shared: bytes32 input is empty"); _; } /// @dev Checks that the pubKeyX is populated modifier nzKey(Key memory key) { require(key.pubKeyX != 0, "Shared: pubKeyX is empty"); _; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "IGovernanceCommunityGuarded.sol"; import "AggKeyNonceConsumer.sol"; import "Shared.sol"; /** * @title GovernanceCommunityGuarded contract * @notice Allows the governor to perform certain actions for the procotol's safety in * case of emergency. The aim is to allow the governor to suspend execution of * critical functions. * Also, it allows the CommunityKey to safeguard certain functions so the * governor can execute them iff the communityKey allows it. */ abstract contract GovernanceCommunityGuarded is Shared, IGovernanceCommunityGuarded { /// @dev Community Guard Disabled bool private _communityGuardDisabled; /// @dev Whether execution is suspended bool private _suspended = false; /** * @notice Get the governor's address. The contracts inheriting this (StateChainGateway and Vault) * get the governor's address from the KeyManager through the AggKeyNonceConsumer's * inheritance. Therefore, the implementation of this function must be left * to the children. This is not implemented as a virtual onlyGovernor modifier to force * the children to implement this function - virtual modifiers don't enforce that. * @return The governor's address */ function _getGovernor() internal view virtual returns (address); /** * @notice Get the community's address. The contracts inheriting this (StateChainGateway and Vault) * get the community's address from the KeyManager through the AggKeyNonceConsumer's * inheritance. Therefore, the implementation of this function must be left * to the children. This is not implemented as a virtual onlyCommunityKey modifier to force * the children to implement this function - virtual modifiers don't enforce that. * @return The community's address */ function _getCommunityKey() internal view virtual returns (address); ////////////////////////////////////////////////////////////// // // // State-changing functions // // // ////////////////////////////////////////////////////////////// /** * @notice Enable Community Guard */ function enableCommunityGuard() external override onlyCommunityKey onlyCommunityGuardDisabled { _communityGuardDisabled = false; emit CommunityGuardDisabled(false); } /** * @notice Disable Community Guard */ function disableCommunityGuard() external override onlyCommunityKey onlyCommunityGuardEnabled { _communityGuardDisabled = true; emit CommunityGuardDisabled(true); } /** * @notice Can be used to suspend contract execution - only executable by * governance and only to be used in case of emergency. */ function suspend() external override onlyGovernor onlyNotSuspended { _suspended = true; emit Suspended(true); } /** * @notice Resume contract execution */ function resume() external override onlyGovernor onlySuspended { _suspended = false; emit Suspended(false); } ////////////////////////////////////////////////////////////// // // // Getters // // // ////////////////////////////////////////////////////////////// /** * @notice Get the Community Key * @return The CommunityKey */ function getCommunityKey() external view override returns (address) { return _getCommunityKey(); } /** * @notice Get the Community Guard state * @return The Community Guard state */ function getCommunityGuardDisabled() external view override returns (bool) { return _communityGuardDisabled; } /** * @notice Get suspended state * @return The suspended state */ function getSuspendedState() external view override returns (bool) { return _suspended; } /** * @notice Get governor address * @return The governor address */ function getGovernor() external view override returns (address) { return _getGovernor(); } ////////////////////////////////////////////////////////////// // // // Modifiers // // // ////////////////////////////////////////////////////////////// /// @dev Check that the caller is the Community Key address. modifier onlyCommunityKey() { require(msg.sender == _getCommunityKey(), "Governance: not Community Key"); _; } /// @dev Check that community has disabled the community guard. modifier onlyCommunityGuardDisabled() { require(_communityGuardDisabled, "Governance: community guard enabled"); _; } /// @dev Check that community has disabled the community guard. modifier onlyCommunityGuardEnabled() { require(!_communityGuardDisabled, "Governance: community guard disabled"); _; } /// @notice Ensure that the caller is the governor address. Calls the getGovernor /// function which is implemented by the children. modifier onlyGovernor() { require(msg.sender == _getGovernor(), "Governance: not governor"); _; } // @notice Check execution is suspended modifier onlySuspended() { require(_suspended, "Governance: not suspended"); _; } // @notice Check execution is not suspended modifier onlyNotSuspended() { require(!_suspended, "Governance: suspended"); _; } }
{ "evmVersion": "paris", "optimizer": { "enabled": true, "runs": 800 }, "libraries": { "StateChainGateway.sol": {} }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"contract IKeyManager","name":"keyManager","type":"address"},{"internalType":"uint256","name":"minFunding","type":"uint256"},{"internalType":"uint48","name":"redemptionDelay","type":"uint48"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"communityGuardDisabled","type":"bool"}],"name":"CommunityGuardDisabled","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"flip","type":"address"}],"name":"FLIPSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldSupply","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newSupply","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"stateChainBlockNumber","type":"uint256"}],"name":"FlipSupplyUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"nodeID","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"address","name":"funder","type":"address"}],"name":"Funded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"GovernanceWithdrawal","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldMinFunding","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newMinFunding","type":"uint256"}],"name":"MinFundingChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"nodeID","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"RedemptionExecuted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"nodeID","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"RedemptionExpired","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"nodeID","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":true,"internalType":"address","name":"redeemAddress","type":"address"},{"indexed":false,"internalType":"uint48","name":"startTime","type":"uint48"},{"indexed":false,"internalType":"uint48","name":"expiryTime","type":"uint48"},{"indexed":false,"internalType":"address","name":"executor","type":"address"}],"name":"RedemptionRegistered","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"suspended","type":"bool"}],"name":"Suspended","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"keyManager","type":"address"}],"name":"UpdatedKeyManager","type":"event"},{"inputs":[],"name":"REDEMPTION_DELAY","outputs":[{"internalType":"uint48","name":"","type":"uint48"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"disableCommunityGuard","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"enableCommunityGuard","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"nodeID","type":"bytes32"}],"name":"executeRedemption","outputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"nodeID","type":"bytes32"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"fundStateChainAccount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getCommunityGuardDisabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCommunityKey","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getFLIP","outputs":[{"internalType":"contract IFLIP","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getGovernor","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getKeyManager","outputs":[{"internalType":"contract IKeyManager","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLastSupplyUpdateBlockNumber","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getMinimumFunding","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"nodeID","type":"bytes32"}],"name":"getPendingRedemption","outputs":[{"components":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"redeemAddress","type":"address"},{"internalType":"uint48","name":"startTime","type":"uint48"},{"internalType":"uint48","name":"expiryTime","type":"uint48"},{"internalType":"address","name":"executor","type":"address"}],"internalType":"struct IStateChainGateway.Redemption","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getSuspendedState","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"govUpdateFlipIssuer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"govWithdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"sig","type":"uint256"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"address","name":"kTimesGAddress","type":"address"}],"internalType":"struct IShared.SigData","name":"sigData","type":"tuple"},{"internalType":"bytes32","name":"nodeID","type":"bytes32"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"redeemAddress","type":"address"},{"internalType":"uint48","name":"expiryTime","type":"uint48"},{"internalType":"address","name":"executor","type":"address"}],"name":"registerRedemption","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"resume","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IFLIP","name":"flip","type":"address"}],"name":"setFlip","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newMinFunding","type":"uint256"}],"name":"setMinFunding","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"suspend","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"sig","type":"uint256"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"address","name":"kTimesGAddress","type":"address"}],"internalType":"struct IShared.SigData","name":"sigData","type":"tuple"},{"internalType":"address","name":"newIssuer","type":"address"},{"internalType":"bool","name":"omitChecks","type":"bool"}],"name":"updateFlipIssuer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"sig","type":"uint256"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"address","name":"kTimesGAddress","type":"address"}],"internalType":"struct IShared.SigData","name":"sigData","type":"tuple"},{"internalType":"uint256","name":"newTotalSupply","type":"uint256"},{"internalType":"uint256","name":"stateChainBlockNumber","type":"uint256"}],"name":"updateFlipSupply","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"sig","type":"uint256"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"address","name":"kTimesGAddress","type":"address"}],"internalType":"struct IShared.SigData","name":"sigData","type":"tuple"},{"internalType":"contract IKeyManager","name":"keyManager","type":"address"},{"internalType":"bool","name":"omitChecks","type":"bool"}],"name":"updateKeyManager","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60a06040526000805460ff60a81b191681556004553480156200002157600080fd5b50604051620028fd380380620028fd833981016040819052620000449162000137565b82806001600160a01b038116620000a25760405162461bcd60e51b815260206004820152601e60248201527f5368617265643a206164647265737320696e70757420697320656d707479000060448201526064015b60405180910390fd5b50600080546001600160a01b0319166001600160a01b039290921691909117815565ffffffffffff8216908190036200011e5760405162461bcd60e51b815260206004820152601b60248201527f5368617265643a2075696e7420696e70757420697320656d7074790000000000604482015260640162000099565b5060029190915565ffffffffffff166080525062000194565b6000806000606084860312156200014d57600080fd5b83516001600160a01b03811681146200016557600080fd5b60208501516040860151919450925065ffffffffffff811681146200018957600080fd5b809150509250925092565b608051612746620001b7600039600081816103ff0152611a1101526127466000f3fe608060405234801561001057600080fd5b50600436106101985760003560e01c80634fc07d75116100e3578063aae9ba431161008c578063e6400bbe11610066578063e6400bbe14610438578063e9dddb9c14610440578063fd4e68471461044857600080fd5b8063aae9ba43146102f0578063ab66b98b146102f8578063e62382c3146103fa57600080fd5b806385cac0df116100bd57806385cac0df146102cd5780638d95e559146102d55780639d9f74bd146102dd57600080fd5b80634fc07d75146102a05780636055409b146102a8578063765849b9146102bb57600080fd5b80633f87b30f11610145578063492764931161011f578063492764931461024a5780634b0cfc001461025d5780634e85ba011461026e57600080fd5b80633f87b30f1461021c578063448cfc8514610224578063470887261461023757600080fd5b8063281e54ce11610176578063281e54ce146101e357806329b74201146101f6578063383d3f701461021457600080fd5b8063046f7da21461019d5780631ae8299c146101a75780632351f495146101d1575b600080fd5b6101a561045b565b005b6001546001600160a01b03165b6040516001600160a01b0390911681526020015b60405180910390f35b6004545b6040519081526020016101c8565b6101a56101f136600461246a565b61055f565b600054600160a81b900460ff165b60405190151581526020016101c8565b6101a561080c565b6101b4610baa565b6101a561023236600461246a565b610bb9565b6101a56102453660046124b4565b610d4d565b6101a56102583660046124d8565b610e69565b6000546001600160a01b03166101b4565b61028161027c36600461250c565b6111c0565b604080516001600160a01b0390931683526020830191909152016101c8565b6101b46114b2565b6101a56102b6366004612525565b6114bc565b600054600160a01b900460ff16610204565b6002546101d5565b6101a561166d565b6101a56102eb366004612547565b611777565b6101a5611c2d565b61039a61030636600461250c565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915250600090815260036020908152604091829020825160a0810184528154815260018201546001600160a01b038082169483019490945265ffffffffffff600160a01b8204811695830195909552600160d01b900490931660608401526002015416608082015290565b6040516101c89190600060a0820190508251825260208301516001600160a01b0380821660208501526040850151915065ffffffffffff808316604086015280606087015116606086015250806080860151166080850152505092915050565b6104217f000000000000000000000000000000000000000000000000000000000000000081565b60405165ffffffffffff90911681526020016101c8565b6101a5611d3f565b6101a5611e38565b6101a561045636600461250c565b61202b565b610463612121565b6001600160a01b0316336001600160a01b0316146104c35760405162461bcd60e51b815260206004820152601860248201527723b7bb32b93730b731b29d103737ba1033b7bb32b93737b960411b60448201526064015b60405180910390fd5b600054600160a81b900460ff1661051c5760405162461bcd60e51b815260206004820152601960248201527f476f7665726e616e63653a206e6f742073757370656e6465640000000000000060448201526064016104ba565b6000805460ff60a81b191681556040519081527f58e6c20b68c19f4d8dbc6206267af40b288342464b433205bb41e5b65c4016da906020015b60405180910390a1565b600054600160a81b900460ff16156105b15760405162461bcd60e51b815260206004820152601560248201527411dbdd995c9b985b98d94e881cdd5cdc195b991959605a1b60448201526064016104ba565b816001600160a01b0381166106085760405162461bcd60e51b815260206004820152601e60248201527f5368617265643a206164647265737320696e70757420697320656d707479000060448201526064016104ba565b6040805163140f2a6760e11b60208201526001600160a01b03851691810191909152821515606082015284906080016040516020818303038152906040528051906020012061065f6000546001600160a01b031690565b6001600160a01b0316632cb2b86283836040518363ffffffff1660e01b815260040161068c9291906125c2565b600060405180830381600087803b1580156106a657600080fd5b505af11580156106ba573d6000803e3d6000fd5b505050508361078e57600154604080516306ba0a6760e21b815290516001600160a01b0392831692881691631ae8299c9160048083019260209291908290030181865afa15801561070f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061073391906125fe565b6001600160a01b0316146107895760405162461bcd60e51b815260206004820152601760248201527f476174657761793a2077726f6e6720464c49502072656600000000000000000060448201526064016104ba565b6107a5565b6000856001600160a01b03163b116107a557600080fd5b600154604051637831243560e01b81526001600160a01b03878116600483015290911690637831243590602401600060405180830381600087803b1580156107ec57600080fd5b505af1158015610800573d6000803e3d6000fd5b50505050505050505050565b610814612121565b6001600160a01b0316336001600160a01b03161461086f5760405162461bcd60e51b815260206004820152601860248201527723b7bb32b93730b731b29d103737ba1033b7bb32b93737b960411b60448201526064016104ba565b600054600160a01b900460ff166108d45760405162461bcd60e51b815260206004820152602360248201527f476f7665726e616e63653a20636f6d6d756e69747920677561726420656e61626044820152621b195960ea1b60648201526084016104ba565b600054600160a81b900460ff1661092d5760405162461bcd60e51b815260206004820152601960248201527f476f7665726e616e63653a206e6f742073757370656e6465640000000000000060448201526064016104ba565b6001546040516370a0823160e01b81523060048201526001600160a01b039091169060009082906370a0823190602401602060405180830381865afa15801561097a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061099e919061261b565b905060006109b46000546001600160a01b031690565b6001600160a01b031663cd1b4d206040518163ffffffff1660e01b8152600401602060405180830381865afa1580156109f1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a1591906125fe565b60405163a9059cbb60e01b81526001600160a01b038083166004830152602482018590529192509084169063a9059cbb906044016020604051808303816000875af1158015610a68573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a8c9190612634565b50604080516001600160a01b0383168152602081018490527ffb698a1f0614fe8250cab73f9e958d9eb3aa668918f243f3638dba6da247643d910160405180910390a1306001600160a01b0316836001600160a01b031663525564216040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b17573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b3b91906125fe565b6001600160a01b031603610ba557604051637831243560e01b81526001600160a01b038281166004830152841690637831243590602401600060405180830381600087803b158015610b8c57600080fd5b505af1158015610ba0573d6000803e3d6000fd5b505050505b505050565b6000610bb461218f565b905090565b816001600160a01b038116610c105760405162461bcd60e51b815260206004820152601e60248201527f5368617265643a206164647265737320696e70757420697320656d707479000060448201526064016104ba565b6040805163448cfc8560e01b60208201526001600160a01b038516918101919091528215156060820152849060800160405160208183030381529060405280519060200120610c676000546001600160a01b031690565b6001600160a01b0316632cb2b86283836040518363ffffffff1660e01b8152600401610c949291906125c2565b600060405180830381600087803b158015610cae57600080fd5b505af1158015610cc2573d6000803e3d6000fd5b505050506000856001600160a01b03163b11610cdd57600080fd5b610ce785856121d9565b6000805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0387169081179091556040519081527fd18040e514983d65f088430e69091aea9bf07feaed3696a3faac1ccc34b5e3bc9060200160405180910390a1505050505050565b806001600160a01b038116610da45760405162461bcd60e51b815260206004820152601e60248201527f5368617265643a206164647265737320696e70757420697320656d707479000060448201526064016104ba565b6001546001600160a01b031615610e075760405162461bcd60e51b815260206004820152602160248201527f476174657761793a20466c6970206164647265737320616c72656164792073656044820152601d60fa1b60648201526084016104ba565b6001805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0384169081179091556040519081527f28a7be5ead6163acf2999fbd7effa68e097435d695eae192ae3121c9b4e502559060200160405180910390a15050565b600054600160a81b900460ff1615610ebb5760405162461bcd60e51b815260206004820152601560248201527411dbdd995c9b985b98d94e881cdd5cdc195b991959605a1b60448201526064016104ba565b8180600003610f0c5760405162461bcd60e51b815260206004820152601b60248201527f5368617265643a2075696e7420696e70757420697320656d707479000000000060448201526064016104ba565b60408051634927649360e01b602082015290810184905260608101839052849060800160405160208183030381529060405280519060200120610f576000546001600160a01b031690565b6001600160a01b0316632cb2b86283836040518363ffffffff1660e01b8152600401610f849291906125c2565b600060405180830381600087803b158015610f9e57600080fd5b505af1158015610fb2573d6000803e3d6000fd5b5050505060045484116110075760405162461bcd60e51b815260206004820152601f60248201527f476174657761793a206f6c6420464c495020737570706c79207570646174650060448201526064016104ba565b6004848155600154604080516318160ddd60e01b815290516001600160a01b039092169260009284926318160ddd92818101926020929091908290030181865afa158015611059573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061107d919061261b565b9050808710156110fc5760006110938883612667565b604051632770a7eb60e21b8152306004820152602481018290529091506001600160a01b03841690639dc29fac90604401600060405180830381600087803b1580156110de57600080fd5b505af11580156110f2573d6000803e3d6000fd5b5050505050611175565b808711156111755760006111108289612667565b6040516340c10f1960e01b8152306004820152602481018290529091506001600160a01b038416906340c10f1990604401600060405180830381600087803b15801561115b57600080fd5b505af115801561116f573d6000803e3d6000fd5b50505050505b60408051828152602081018990529081018790527fff4b7a826623672c6944dc44d809008e2e1105180d110fd63986e841f15eb2ad9060600160405180910390a15050505050505050565b600080548190600160a81b900460ff16156112155760405162461bcd60e51b815260206004820152601560248201527411dbdd995c9b985b98d94e881cdd5cdc195b991959605a1b60448201526064016104ba565b600083815260036020908152604091829020825160a0810184528154815260018201546001600160a01b038082169483019490945265ffffffffffff600160a01b82048116958301869052600160d01b909104166060820152600290910154909116608082015290421080159061129857506000816060015165ffffffffffff16115b6112e45760405162461bcd60e51b815260206004820152601f60248201527f476174657761793a206561726c79206f7220616c72656164792065786563640060448201526064016104ba565b60008481526003602052604081208181556001810191909155600201805473ffffffffffffffffffffffffffffffffffffffff19169055606081015165ffffffffffff16421161146d5760808101516001600160a01b0316156113a65780608001516001600160a01b0316336001600160a01b0316146113a65760405162461bcd60e51b815260206004820152601560248201527f476174657761793a206e6f74206578656375746f72000000000000000000000060448201526064016104ba565b805160405190815284907f2b917410dde505b91c1ee8bf49bc98c4d80f9f6fde62c4aad7743e5c3fcd568f9060200160405180910390a26001546020820151825160405163a9059cbb60e01b81526001600160a01b039283166004820152602481019190915291169063a9059cbb906044016020604051808303816000875af1158015611437573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061145b9190612634565b50602081015190519092509050915091565b805160405190815284907f2e395ce432fa118cf9b801546bae2c36a87aa9b514af0bec0df46bb534513de59060200160405180910390a2602001519360009350915050565b6000610bb4612121565b818061150a5760405162461bcd60e51b815260206004820152601e60248201527f5368617265643a206279746573333220696e70757420697320656d707479000060448201526064016104ba565b6001546001600160a01b0316806115635760405162461bcd60e51b815260206004820152601560248201527f476174657761793a20466c6970206e6f7420736574000000000000000000000060448201526064016104ba565b6002548310156115b55760405162461bcd60e51b815260206004820152601960248201527f476174657761793a206e6f7420656e6f7567682066756e64730000000000000060448201526064016104ba565b6040516323b872dd60e01b8152336004820152306024820152604481018490526001600160a01b038216906323b872dd906064016020604051808303816000875af1158015611608573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061162c9190612634565b506040805184815233602082015285917fc1b5c1b3c1e294059714af16e812402029c9d8bf1d0d89770d3ff069dddc48db910160405180910390a250505050565b61167561218f565b6001600160a01b0316336001600160a01b0316146116d55760405162461bcd60e51b815260206004820152601d60248201527f476f7665726e616e63653a206e6f7420436f6d6d756e697479204b657900000060448201526064016104ba565b600054600160a01b900460ff1661173a5760405162461bcd60e51b815260206004820152602360248201527f476f7665726e616e63653a20636f6d6d756e69747920677561726420656e61626044820152621b195960ea1b60648201526084016104ba565b6000805460ff60a01b191681556040519081527f057c4cb09f128960151f04372028154acda40272f16360154961672989b59bad90602001610555565b600054600160a81b900460ff16156117c95760405162461bcd60e51b815260206004820152601560248201527411dbdd995c9b985b98d94e881cdd5cdc195b991959605a1b60448201526064016104ba565b84806118175760405162461bcd60e51b815260206004820152601e60248201527f5368617265643a206279746573333220696e70757420697320656d707479000060448201526064016104ba565b84806000036118685760405162461bcd60e51b815260206004820152601b60248201527f5368617265643a2075696e7420696e70757420697320656d707479000000000060448201526064016104ba565b846001600160a01b0381166118bf5760405162461bcd60e51b815260206004820152601e60248201527f5368617265643a206164647265737320696e70757420697320656d707479000060448201526064016104ba565b60408051639d9f74bd60e01b6020820152908101899052606081018890526001600160a01b03808816608083015265ffffffffffff871660a0830152851660c0820152899060e0016040516020818303038152906040528051906020012061192f6000546001600160a01b031690565b6001600160a01b0316632cb2b86283836040518363ffffffff1660e01b815260040161195c9291906125c2565b600060405180830381600087803b15801561197657600080fd5b505af115801561198a573d6000803e3d6000fd5b50505060008b815260036020526040902060010154600160d01b900465ffffffffffff1642119050611a0a5760405162461bcd60e51b8152602060048201526024808201527f476174657761793a20612070656e64696e6720726564656d7074696f6e2065786044820152636973747360e01b60648201526084016104ba565b6000611a367f000000000000000000000000000000000000000000000000000000000000000042612680565b90508065ffffffffffff168865ffffffffffff1611611a975760405162461bcd60e51b815260206004820152601d60248201527f476174657761793a206578706972792074696d6520746f6f20736f6f6e00000060448201526064016104ba565b6040518060a001604052808b81526020018a6001600160a01b031681526020018265ffffffffffff1681526020018965ffffffffffff168152602001886001600160a01b0316815250600360008d81526020019081526020016000206000820151816000015560208201518160010160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060408201518160010160146101000a81548165ffffffffffff021916908365ffffffffffff160217905550606082015181600101601a6101000a81548165ffffffffffff021916908365ffffffffffff16021790555060808201518160020160006101000a8154816001600160a01b0302191690836001600160a01b03160217905550905050886001600160a01b03168b7e595d7bd66cc5e1bac8c1f380818b52987790a5b3b3cbc753a7945469be2cd88c848c8c604051611c17949392919093845265ffffffffffff9283166020850152911660408301526001600160a01b0316606082015260800190565b60405180910390a3505050505050505050505050565b611c3561218f565b6001600160a01b0316336001600160a01b031614611c955760405162461bcd60e51b815260206004820152601d60248201527f476f7665726e616e63653a206e6f7420436f6d6d756e697479204b657900000060448201526064016104ba565b600054600160a01b900460ff1615611cfb5760405162461bcd60e51b8152602060048201526024808201527f476f7665726e616e63653a20636f6d6d756e6974792067756172642064697361604482015263189b195960e21b60648201526084016104ba565b6000805460ff60a01b1916600160a01b179055604051600181527f057c4cb09f128960151f04372028154acda40272f16360154961672989b59bad90602001610555565b611d47612121565b6001600160a01b0316336001600160a01b031614611da25760405162461bcd60e51b815260206004820152601860248201527723b7bb32b93730b731b29d103737ba1033b7bb32b93737b960411b60448201526064016104ba565b600054600160a81b900460ff1615611df45760405162461bcd60e51b815260206004820152601560248201527411dbdd995c9b985b98d94e881cdd5cdc195b991959605a1b60448201526064016104ba565b6000805460ff60a81b1916600160a81b179055604051600181527f58e6c20b68c19f4d8dbc6206267af40b288342464b433205bb41e5b65c4016da90602001610555565b611e40612121565b6001600160a01b0316336001600160a01b031614611e9b5760405162461bcd60e51b815260206004820152601860248201527723b7bb32b93730b731b29d103737ba1033b7bb32b93737b960411b60448201526064016104ba565b600054600160a01b900460ff16611f005760405162461bcd60e51b815260206004820152602360248201527f476f7665726e616e63653a20636f6d6d756e69747920677561726420656e61626044820152621b195960ea1b60648201526084016104ba565b600054600160a81b900460ff16611f595760405162461bcd60e51b815260206004820152601960248201527f476f7665726e616e63653a206e6f742073757370656e6465640000000000000060448201526064016104ba565b600080546001600160a01b03166001600160a01b031663cd1b4d206040518163ffffffff1660e01b8152600401602060405180830381865afa158015611fa3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fc791906125fe565b600154604051637831243560e01b81526001600160a01b038084166004830152929350911690637831243590602401600060405180830381600087803b15801561201057600080fd5b505af1158015612024573d6000803e3d6000fd5b5050505050565b808060000361207c5760405162461bcd60e51b815260206004820152601b60248201527f5368617265643a2075696e7420696e70757420697320656d707479000000000060448201526064016104ba565b612084612121565b6001600160a01b0316336001600160a01b0316146120df5760405162461bcd60e51b815260206004820152601860248201527723b7bb32b93730b731b29d103737ba1033b7bb32b93737b960411b60448201526064016104ba565b60025460408051918252602082018490527f09c1d94393b22192a9e1fc232a9accb31e0c1ad78f42b2f42f9da84e9931d16d910160405180910390a150600255565b600080546001600160a01b03166001600160a01b031663cd1b4d206040518163ffffffff1660e01b8152600401602060405180830381865afa15801561216b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bb491906125fe565b600080546001600160a01b03166001600160a01b0316633f87b30f6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561216b573d6000803e3d6000fd5b6000826001600160a01b031663cd1b4d206040518163ffffffff1660e01b8152600401602060405180830381865afa158015612219573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061223d91906125fe565b90506000836001600160a01b0316633f87b30f6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561227f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122a391906125fe565b9050826123fd576122b2612121565b6001600160a01b0316826001600160a01b03161480156122ea57506122d561218f565b6001600160a01b0316816001600160a01b0316145b6122f357600080fd5b6000846001600160a01b031663d5b9c0366040518163ffffffff1660e01b81526004016040805180830381865afa158015612332573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061235691906126a6565b9050600061236c6000546001600160a01b031690565b6001600160a01b031663d5b9c0366040518163ffffffff1660e01b81526004016040805180830381865afa1580156123a8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123cc91906126a6565b805183519192501480156123ed5750806020015160ff16826020015160ff16145b6123f657600080fd5b5050612426565b6001600160a01b0382161580159061241d57506001600160a01b03811615155b61242657600080fd5b50505050565b60006060828403121561243e57600080fd5b50919050565b6001600160a01b038116811461245957600080fd5b50565b801515811461245957600080fd5b600080600060a0848603121561247f57600080fd5b612489858561242c565b9250606084013561249981612444565b915060808401356124a98161245c565b809150509250925092565b6000602082840312156124c657600080fd5b81356124d181612444565b9392505050565b600080600060a084860312156124ed57600080fd5b6124f7858561242c565b95606085013595506080909401359392505050565b60006020828403121561251e57600080fd5b5035919050565b6000806040838503121561253857600080fd5b50508035926020909101359150565b600080600080600080610100878903121561256157600080fd5b61256b888861242c565b9550606087013594506080870135935060a087013561258981612444565b925060c087013565ffffffffffff811681146125a457600080fd5b915060e08701356125b481612444565b809150509295509295509295565b82358152602080840135908201526080810160408401356125e281612444565b6001600160a01b03166040830152606090910191909152919050565b60006020828403121561261057600080fd5b81516124d181612444565b60006020828403121561262d57600080fd5b5051919050565b60006020828403121561264657600080fd5b81516124d18161245c565b634e487b7160e01b600052601160045260246000fd5b8181038181111561267a5761267a612651565b92915050565b65ffffffffffff81811683821601908082111561269f5761269f612651565b5092915050565b6000604082840312156126b857600080fd5b6040516040810181811067ffffffffffffffff821117156126e957634e487b7160e01b600052604160045260246000fd5b60405282518152602083015160ff8116811461270457600080fd5b6020820152939250505056fea264697066735822122074762e1f49f40fa09b7b96be9157adb83d1b428abbe8b3985abd9ac21eb390fc64736f6c63430008140033000000000000000000000000cd351d3626dc244730796a3168d315168ebf08be0000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000000000000000000000000000000000000002a300
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106101985760003560e01c80634fc07d75116100e3578063aae9ba431161008c578063e6400bbe11610066578063e6400bbe14610438578063e9dddb9c14610440578063fd4e68471461044857600080fd5b8063aae9ba43146102f0578063ab66b98b146102f8578063e62382c3146103fa57600080fd5b806385cac0df116100bd57806385cac0df146102cd5780638d95e559146102d55780639d9f74bd146102dd57600080fd5b80634fc07d75146102a05780636055409b146102a8578063765849b9146102bb57600080fd5b80633f87b30f11610145578063492764931161011f578063492764931461024a5780634b0cfc001461025d5780634e85ba011461026e57600080fd5b80633f87b30f1461021c578063448cfc8514610224578063470887261461023757600080fd5b8063281e54ce11610176578063281e54ce146101e357806329b74201146101f6578063383d3f701461021457600080fd5b8063046f7da21461019d5780631ae8299c146101a75780632351f495146101d1575b600080fd5b6101a561045b565b005b6001546001600160a01b03165b6040516001600160a01b0390911681526020015b60405180910390f35b6004545b6040519081526020016101c8565b6101a56101f136600461246a565b61055f565b600054600160a81b900460ff165b60405190151581526020016101c8565b6101a561080c565b6101b4610baa565b6101a561023236600461246a565b610bb9565b6101a56102453660046124b4565b610d4d565b6101a56102583660046124d8565b610e69565b6000546001600160a01b03166101b4565b61028161027c36600461250c565b6111c0565b604080516001600160a01b0390931683526020830191909152016101c8565b6101b46114b2565b6101a56102b6366004612525565b6114bc565b600054600160a01b900460ff16610204565b6002546101d5565b6101a561166d565b6101a56102eb366004612547565b611777565b6101a5611c2d565b61039a61030636600461250c565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915250600090815260036020908152604091829020825160a0810184528154815260018201546001600160a01b038082169483019490945265ffffffffffff600160a01b8204811695830195909552600160d01b900490931660608401526002015416608082015290565b6040516101c89190600060a0820190508251825260208301516001600160a01b0380821660208501526040850151915065ffffffffffff808316604086015280606087015116606086015250806080860151166080850152505092915050565b6104217f000000000000000000000000000000000000000000000000000000000002a30081565b60405165ffffffffffff90911681526020016101c8565b6101a5611d3f565b6101a5611e38565b6101a561045636600461250c565b61202b565b610463612121565b6001600160a01b0316336001600160a01b0316146104c35760405162461bcd60e51b815260206004820152601860248201527723b7bb32b93730b731b29d103737ba1033b7bb32b93737b960411b60448201526064015b60405180910390fd5b600054600160a81b900460ff1661051c5760405162461bcd60e51b815260206004820152601960248201527f476f7665726e616e63653a206e6f742073757370656e6465640000000000000060448201526064016104ba565b6000805460ff60a81b191681556040519081527f58e6c20b68c19f4d8dbc6206267af40b288342464b433205bb41e5b65c4016da906020015b60405180910390a1565b600054600160a81b900460ff16156105b15760405162461bcd60e51b815260206004820152601560248201527411dbdd995c9b985b98d94e881cdd5cdc195b991959605a1b60448201526064016104ba565b816001600160a01b0381166106085760405162461bcd60e51b815260206004820152601e60248201527f5368617265643a206164647265737320696e70757420697320656d707479000060448201526064016104ba565b6040805163140f2a6760e11b60208201526001600160a01b03851691810191909152821515606082015284906080016040516020818303038152906040528051906020012061065f6000546001600160a01b031690565b6001600160a01b0316632cb2b86283836040518363ffffffff1660e01b815260040161068c9291906125c2565b600060405180830381600087803b1580156106a657600080fd5b505af11580156106ba573d6000803e3d6000fd5b505050508361078e57600154604080516306ba0a6760e21b815290516001600160a01b0392831692881691631ae8299c9160048083019260209291908290030181865afa15801561070f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061073391906125fe565b6001600160a01b0316146107895760405162461bcd60e51b815260206004820152601760248201527f476174657761793a2077726f6e6720464c49502072656600000000000000000060448201526064016104ba565b6107a5565b6000856001600160a01b03163b116107a557600080fd5b600154604051637831243560e01b81526001600160a01b03878116600483015290911690637831243590602401600060405180830381600087803b1580156107ec57600080fd5b505af1158015610800573d6000803e3d6000fd5b50505050505050505050565b610814612121565b6001600160a01b0316336001600160a01b03161461086f5760405162461bcd60e51b815260206004820152601860248201527723b7bb32b93730b731b29d103737ba1033b7bb32b93737b960411b60448201526064016104ba565b600054600160a01b900460ff166108d45760405162461bcd60e51b815260206004820152602360248201527f476f7665726e616e63653a20636f6d6d756e69747920677561726420656e61626044820152621b195960ea1b60648201526084016104ba565b600054600160a81b900460ff1661092d5760405162461bcd60e51b815260206004820152601960248201527f476f7665726e616e63653a206e6f742073757370656e6465640000000000000060448201526064016104ba565b6001546040516370a0823160e01b81523060048201526001600160a01b039091169060009082906370a0823190602401602060405180830381865afa15801561097a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061099e919061261b565b905060006109b46000546001600160a01b031690565b6001600160a01b031663cd1b4d206040518163ffffffff1660e01b8152600401602060405180830381865afa1580156109f1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a1591906125fe565b60405163a9059cbb60e01b81526001600160a01b038083166004830152602482018590529192509084169063a9059cbb906044016020604051808303816000875af1158015610a68573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a8c9190612634565b50604080516001600160a01b0383168152602081018490527ffb698a1f0614fe8250cab73f9e958d9eb3aa668918f243f3638dba6da247643d910160405180910390a1306001600160a01b0316836001600160a01b031663525564216040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b17573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b3b91906125fe565b6001600160a01b031603610ba557604051637831243560e01b81526001600160a01b038281166004830152841690637831243590602401600060405180830381600087803b158015610b8c57600080fd5b505af1158015610ba0573d6000803e3d6000fd5b505050505b505050565b6000610bb461218f565b905090565b816001600160a01b038116610c105760405162461bcd60e51b815260206004820152601e60248201527f5368617265643a206164647265737320696e70757420697320656d707479000060448201526064016104ba565b6040805163448cfc8560e01b60208201526001600160a01b038516918101919091528215156060820152849060800160405160208183030381529060405280519060200120610c676000546001600160a01b031690565b6001600160a01b0316632cb2b86283836040518363ffffffff1660e01b8152600401610c949291906125c2565b600060405180830381600087803b158015610cae57600080fd5b505af1158015610cc2573d6000803e3d6000fd5b505050506000856001600160a01b03163b11610cdd57600080fd5b610ce785856121d9565b6000805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0387169081179091556040519081527fd18040e514983d65f088430e69091aea9bf07feaed3696a3faac1ccc34b5e3bc9060200160405180910390a1505050505050565b806001600160a01b038116610da45760405162461bcd60e51b815260206004820152601e60248201527f5368617265643a206164647265737320696e70757420697320656d707479000060448201526064016104ba565b6001546001600160a01b031615610e075760405162461bcd60e51b815260206004820152602160248201527f476174657761793a20466c6970206164647265737320616c72656164792073656044820152601d60fa1b60648201526084016104ba565b6001805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0384169081179091556040519081527f28a7be5ead6163acf2999fbd7effa68e097435d695eae192ae3121c9b4e502559060200160405180910390a15050565b600054600160a81b900460ff1615610ebb5760405162461bcd60e51b815260206004820152601560248201527411dbdd995c9b985b98d94e881cdd5cdc195b991959605a1b60448201526064016104ba565b8180600003610f0c5760405162461bcd60e51b815260206004820152601b60248201527f5368617265643a2075696e7420696e70757420697320656d707479000000000060448201526064016104ba565b60408051634927649360e01b602082015290810184905260608101839052849060800160405160208183030381529060405280519060200120610f576000546001600160a01b031690565b6001600160a01b0316632cb2b86283836040518363ffffffff1660e01b8152600401610f849291906125c2565b600060405180830381600087803b158015610f9e57600080fd5b505af1158015610fb2573d6000803e3d6000fd5b5050505060045484116110075760405162461bcd60e51b815260206004820152601f60248201527f476174657761793a206f6c6420464c495020737570706c79207570646174650060448201526064016104ba565b6004848155600154604080516318160ddd60e01b815290516001600160a01b039092169260009284926318160ddd92818101926020929091908290030181865afa158015611059573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061107d919061261b565b9050808710156110fc5760006110938883612667565b604051632770a7eb60e21b8152306004820152602481018290529091506001600160a01b03841690639dc29fac90604401600060405180830381600087803b1580156110de57600080fd5b505af11580156110f2573d6000803e3d6000fd5b5050505050611175565b808711156111755760006111108289612667565b6040516340c10f1960e01b8152306004820152602481018290529091506001600160a01b038416906340c10f1990604401600060405180830381600087803b15801561115b57600080fd5b505af115801561116f573d6000803e3d6000fd5b50505050505b60408051828152602081018990529081018790527fff4b7a826623672c6944dc44d809008e2e1105180d110fd63986e841f15eb2ad9060600160405180910390a15050505050505050565b600080548190600160a81b900460ff16156112155760405162461bcd60e51b815260206004820152601560248201527411dbdd995c9b985b98d94e881cdd5cdc195b991959605a1b60448201526064016104ba565b600083815260036020908152604091829020825160a0810184528154815260018201546001600160a01b038082169483019490945265ffffffffffff600160a01b82048116958301869052600160d01b909104166060820152600290910154909116608082015290421080159061129857506000816060015165ffffffffffff16115b6112e45760405162461bcd60e51b815260206004820152601f60248201527f476174657761793a206561726c79206f7220616c72656164792065786563640060448201526064016104ba565b60008481526003602052604081208181556001810191909155600201805473ffffffffffffffffffffffffffffffffffffffff19169055606081015165ffffffffffff16421161146d5760808101516001600160a01b0316156113a65780608001516001600160a01b0316336001600160a01b0316146113a65760405162461bcd60e51b815260206004820152601560248201527f476174657761793a206e6f74206578656375746f72000000000000000000000060448201526064016104ba565b805160405190815284907f2b917410dde505b91c1ee8bf49bc98c4d80f9f6fde62c4aad7743e5c3fcd568f9060200160405180910390a26001546020820151825160405163a9059cbb60e01b81526001600160a01b039283166004820152602481019190915291169063a9059cbb906044016020604051808303816000875af1158015611437573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061145b9190612634565b50602081015190519092509050915091565b805160405190815284907f2e395ce432fa118cf9b801546bae2c36a87aa9b514af0bec0df46bb534513de59060200160405180910390a2602001519360009350915050565b6000610bb4612121565b818061150a5760405162461bcd60e51b815260206004820152601e60248201527f5368617265643a206279746573333220696e70757420697320656d707479000060448201526064016104ba565b6001546001600160a01b0316806115635760405162461bcd60e51b815260206004820152601560248201527f476174657761793a20466c6970206e6f7420736574000000000000000000000060448201526064016104ba565b6002548310156115b55760405162461bcd60e51b815260206004820152601960248201527f476174657761793a206e6f7420656e6f7567682066756e64730000000000000060448201526064016104ba565b6040516323b872dd60e01b8152336004820152306024820152604481018490526001600160a01b038216906323b872dd906064016020604051808303816000875af1158015611608573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061162c9190612634565b506040805184815233602082015285917fc1b5c1b3c1e294059714af16e812402029c9d8bf1d0d89770d3ff069dddc48db910160405180910390a250505050565b61167561218f565b6001600160a01b0316336001600160a01b0316146116d55760405162461bcd60e51b815260206004820152601d60248201527f476f7665726e616e63653a206e6f7420436f6d6d756e697479204b657900000060448201526064016104ba565b600054600160a01b900460ff1661173a5760405162461bcd60e51b815260206004820152602360248201527f476f7665726e616e63653a20636f6d6d756e69747920677561726420656e61626044820152621b195960ea1b60648201526084016104ba565b6000805460ff60a01b191681556040519081527f057c4cb09f128960151f04372028154acda40272f16360154961672989b59bad90602001610555565b600054600160a81b900460ff16156117c95760405162461bcd60e51b815260206004820152601560248201527411dbdd995c9b985b98d94e881cdd5cdc195b991959605a1b60448201526064016104ba565b84806118175760405162461bcd60e51b815260206004820152601e60248201527f5368617265643a206279746573333220696e70757420697320656d707479000060448201526064016104ba565b84806000036118685760405162461bcd60e51b815260206004820152601b60248201527f5368617265643a2075696e7420696e70757420697320656d707479000000000060448201526064016104ba565b846001600160a01b0381166118bf5760405162461bcd60e51b815260206004820152601e60248201527f5368617265643a206164647265737320696e70757420697320656d707479000060448201526064016104ba565b60408051639d9f74bd60e01b6020820152908101899052606081018890526001600160a01b03808816608083015265ffffffffffff871660a0830152851660c0820152899060e0016040516020818303038152906040528051906020012061192f6000546001600160a01b031690565b6001600160a01b0316632cb2b86283836040518363ffffffff1660e01b815260040161195c9291906125c2565b600060405180830381600087803b15801561197657600080fd5b505af115801561198a573d6000803e3d6000fd5b50505060008b815260036020526040902060010154600160d01b900465ffffffffffff1642119050611a0a5760405162461bcd60e51b8152602060048201526024808201527f476174657761793a20612070656e64696e6720726564656d7074696f6e2065786044820152636973747360e01b60648201526084016104ba565b6000611a367f000000000000000000000000000000000000000000000000000000000002a30042612680565b90508065ffffffffffff168865ffffffffffff1611611a975760405162461bcd60e51b815260206004820152601d60248201527f476174657761793a206578706972792074696d6520746f6f20736f6f6e00000060448201526064016104ba565b6040518060a001604052808b81526020018a6001600160a01b031681526020018265ffffffffffff1681526020018965ffffffffffff168152602001886001600160a01b0316815250600360008d81526020019081526020016000206000820151816000015560208201518160010160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060408201518160010160146101000a81548165ffffffffffff021916908365ffffffffffff160217905550606082015181600101601a6101000a81548165ffffffffffff021916908365ffffffffffff16021790555060808201518160020160006101000a8154816001600160a01b0302191690836001600160a01b03160217905550905050886001600160a01b03168b7e595d7bd66cc5e1bac8c1f380818b52987790a5b3b3cbc753a7945469be2cd88c848c8c604051611c17949392919093845265ffffffffffff9283166020850152911660408301526001600160a01b0316606082015260800190565b60405180910390a3505050505050505050505050565b611c3561218f565b6001600160a01b0316336001600160a01b031614611c955760405162461bcd60e51b815260206004820152601d60248201527f476f7665726e616e63653a206e6f7420436f6d6d756e697479204b657900000060448201526064016104ba565b600054600160a01b900460ff1615611cfb5760405162461bcd60e51b8152602060048201526024808201527f476f7665726e616e63653a20636f6d6d756e6974792067756172642064697361604482015263189b195960e21b60648201526084016104ba565b6000805460ff60a01b1916600160a01b179055604051600181527f057c4cb09f128960151f04372028154acda40272f16360154961672989b59bad90602001610555565b611d47612121565b6001600160a01b0316336001600160a01b031614611da25760405162461bcd60e51b815260206004820152601860248201527723b7bb32b93730b731b29d103737ba1033b7bb32b93737b960411b60448201526064016104ba565b600054600160a81b900460ff1615611df45760405162461bcd60e51b815260206004820152601560248201527411dbdd995c9b985b98d94e881cdd5cdc195b991959605a1b60448201526064016104ba565b6000805460ff60a81b1916600160a81b179055604051600181527f58e6c20b68c19f4d8dbc6206267af40b288342464b433205bb41e5b65c4016da90602001610555565b611e40612121565b6001600160a01b0316336001600160a01b031614611e9b5760405162461bcd60e51b815260206004820152601860248201527723b7bb32b93730b731b29d103737ba1033b7bb32b93737b960411b60448201526064016104ba565b600054600160a01b900460ff16611f005760405162461bcd60e51b815260206004820152602360248201527f476f7665726e616e63653a20636f6d6d756e69747920677561726420656e61626044820152621b195960ea1b60648201526084016104ba565b600054600160a81b900460ff16611f595760405162461bcd60e51b815260206004820152601960248201527f476f7665726e616e63653a206e6f742073757370656e6465640000000000000060448201526064016104ba565b600080546001600160a01b03166001600160a01b031663cd1b4d206040518163ffffffff1660e01b8152600401602060405180830381865afa158015611fa3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fc791906125fe565b600154604051637831243560e01b81526001600160a01b038084166004830152929350911690637831243590602401600060405180830381600087803b15801561201057600080fd5b505af1158015612024573d6000803e3d6000fd5b5050505050565b808060000361207c5760405162461bcd60e51b815260206004820152601b60248201527f5368617265643a2075696e7420696e70757420697320656d707479000000000060448201526064016104ba565b612084612121565b6001600160a01b0316336001600160a01b0316146120df5760405162461bcd60e51b815260206004820152601860248201527723b7bb32b93730b731b29d103737ba1033b7bb32b93737b960411b60448201526064016104ba565b60025460408051918252602082018490527f09c1d94393b22192a9e1fc232a9accb31e0c1ad78f42b2f42f9da84e9931d16d910160405180910390a150600255565b600080546001600160a01b03166001600160a01b031663cd1b4d206040518163ffffffff1660e01b8152600401602060405180830381865afa15801561216b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bb491906125fe565b600080546001600160a01b03166001600160a01b0316633f87b30f6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561216b573d6000803e3d6000fd5b6000826001600160a01b031663cd1b4d206040518163ffffffff1660e01b8152600401602060405180830381865afa158015612219573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061223d91906125fe565b90506000836001600160a01b0316633f87b30f6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561227f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122a391906125fe565b9050826123fd576122b2612121565b6001600160a01b0316826001600160a01b03161480156122ea57506122d561218f565b6001600160a01b0316816001600160a01b0316145b6122f357600080fd5b6000846001600160a01b031663d5b9c0366040518163ffffffff1660e01b81526004016040805180830381865afa158015612332573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061235691906126a6565b9050600061236c6000546001600160a01b031690565b6001600160a01b031663d5b9c0366040518163ffffffff1660e01b81526004016040805180830381865afa1580156123a8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123cc91906126a6565b805183519192501480156123ed5750806020015160ff16826020015160ff16145b6123f657600080fd5b5050612426565b6001600160a01b0382161580159061241d57506001600160a01b03811615155b61242657600080fd5b50505050565b60006060828403121561243e57600080fd5b50919050565b6001600160a01b038116811461245957600080fd5b50565b801515811461245957600080fd5b600080600060a0848603121561247f57600080fd5b612489858561242c565b9250606084013561249981612444565b915060808401356124a98161245c565b809150509250925092565b6000602082840312156124c657600080fd5b81356124d181612444565b9392505050565b600080600060a084860312156124ed57600080fd5b6124f7858561242c565b95606085013595506080909401359392505050565b60006020828403121561251e57600080fd5b5035919050565b6000806040838503121561253857600080fd5b50508035926020909101359150565b600080600080600080610100878903121561256157600080fd5b61256b888861242c565b9550606087013594506080870135935060a087013561258981612444565b925060c087013565ffffffffffff811681146125a457600080fd5b915060e08701356125b481612444565b809150509295509295509295565b82358152602080840135908201526080810160408401356125e281612444565b6001600160a01b03166040830152606090910191909152919050565b60006020828403121561261057600080fd5b81516124d181612444565b60006020828403121561262d57600080fd5b5051919050565b60006020828403121561264657600080fd5b81516124d18161245c565b634e487b7160e01b600052601160045260246000fd5b8181038181111561267a5761267a612651565b92915050565b65ffffffffffff81811683821601908082111561269f5761269f612651565b5092915050565b6000604082840312156126b857600080fd5b6040516040810181811067ffffffffffffffff821117156126e957634e487b7160e01b600052604160045260246000fd5b60405282518152602083015160ff8116811461270457600080fd5b6020820152939250505056fea264697066735822122074762e1f49f40fa09b7b96be9157adb83d1b428abbe8b3985abd9ac21eb390fc64736f6c63430008140033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000cd351d3626dc244730796a3168d315168ebf08be0000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000000000000000000000000000000000000002a300
-----Decoded View---------------
Arg [0] : keyManager (address): 0xcd351d3626Dc244730796A3168D315168eBf08Be
Arg [1] : minFunding (uint256): 1000000000000000000
Arg [2] : redemptionDelay (uint48): 172800
-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 000000000000000000000000cd351d3626dc244730796a3168d315168ebf08be
Arg [1] : 0000000000000000000000000000000000000000000000000de0b6b3a7640000
Arg [2] : 000000000000000000000000000000000000000000000000000000000002a300
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|---|---|---|---|---|
ETH | 100.00% | $1.11 | 49,384,289.7932 | $54,816,561.67 |
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.