Source Code
Latest 25 from a total of 6,056 transactions
| Transaction Hash |
Method
|
Block
|
From
|
|
To
|
||||
|---|---|---|---|---|---|---|---|---|---|
| Register Redempt... | 24429637 | 5 hrs ago | IN | 0 ETH | 0.00000547 | ||||
| Execute Redempti... | 24428351 | 10 hrs ago | IN | 0 ETH | 0.00006525 | ||||
| Fund State Chain... | 24428332 | 10 hrs ago | IN | 0 ETH | 0.00004189 | ||||
| Register Redempt... | 24427277 | 13 hrs ago | IN | 0 ETH | 0.00002059 | ||||
| Fund State Chain... | 24427271 | 13 hrs ago | IN | 0 ETH | 0.00004689 | ||||
| Register Redempt... | 24427192 | 14 hrs ago | IN | 0 ETH | 0.00002943 | ||||
| Register Redempt... | 24427135 | 14 hrs ago | IN | 0 ETH | 0.00003137 | ||||
| Register Redempt... | 24427060 | 14 hrs ago | IN | 0 ETH | 0.00001913 | ||||
| Register Redempt... | 24425989 | 18 hrs ago | IN | 0 ETH | 0.00000966 | ||||
| Register Redempt... | 24425929 | 18 hrs ago | IN | 0 ETH | 0.00000674 | ||||
| Execute Redempti... | 24425866 | 18 hrs ago | IN | 0 ETH | 0.00006338 | ||||
| Update Flip Supp... | 24425482 | 19 hrs ago | IN | 0 ETH | 0.00000686 | ||||
| Register Redempt... | 24425463 | 20 hrs ago | IN | 0 ETH | 0.00000682 | ||||
| Fund State Chain... | 24422752 | 29 hrs ago | IN | 0 ETH | 0.00000227 | ||||
| Fund State Chain... | 24420809 | 35 hrs ago | IN | 0 ETH | 0.00005947 | ||||
| Update Flip Supp... | 24418261 | 44 hrs ago | IN | 0 ETH | 0.00000448 | ||||
| Register Redempt... | 24417863 | 45 hrs ago | IN | 0 ETH | 0.00000491 | ||||
| Execute Redempti... | 24416190 | 2 days ago | IN | 0 ETH | 0.00013013 | ||||
| Update Flip Supp... | 24411063 | 2 days ago | IN | 0 ETH | 0.00000548 | ||||
| Execute Redempti... | 24408169 | 3 days ago | IN | 0 ETH | 0.00013267 | ||||
| Register Redempt... | 24407702 | 3 days ago | IN | 0 ETH | 0.00000808 | ||||
| Execute Redempti... | 24407685 | 3 days ago | IN | 0 ETH | 0.00002914 | ||||
| Execute Redempti... | 24407444 | 3 days ago | IN | 0 ETH | 0.00006268 | ||||
| Update Flip Supp... | 24403874 | 3 days ago | IN | 0 ETH | 0.00001537 | ||||
| Register Redempt... | 24401094 | 4 days ago | IN | 0 ETH | 0.00002642 |
Latest 1 internal transaction
Advanced mode:
| Parent Transaction Hash | Method | Block |
From
|
|
To
|
||
|---|---|---|---|---|---|---|---|
| 0x60a06040 | 18277081 | 860 days ago | Contract Creation | 0 ETH |
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions
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
Contract ABI
API[{"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
Net Worth in USD
$13,955,467.99
Net Worth in ETH
7,058.36873
Token Allocations
FLIP
100.00%
Multichain Portfolio | 34 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|---|---|---|---|---|
| ETH | 100.00% | $0.374856 | 37,228,877.1921 | $13,955,467.99 |
Loading...
Loading
Loading...
Loading
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.