Goerli Testnet

Contract

0x38AA40B7b5a70d738baBf6699a45DacdDBBEB3fc
Transaction Hash
Method
Block
From
To
Value
Update Flip Supp...106639792024-03-13 6:20:1237 days ago1710310812IN
0x38AA40B7...dDBBEB3fc
0 ETH0.00014151.50000001
Fund State Chain...106630352024-03-12 13:13:2438 days ago1710249204IN
0x38AA40B7...dDBBEB3fc
0 ETH0.000069581.50000073
Update Flip Supp...106625252024-03-12 6:05:1238 days ago1710223512IN
0x38AA40B7...dDBBEB3fc
0 ETH0.00014151.50000001
Update Flip Supp...106607242024-03-11 5:56:3639 days ago1710136596IN
0x38AA40B7...dDBBEB3fc
0 ETH0.000188692.00000001
Update Flip Supp...106583972024-03-10 5:44:1240 days ago1710049452IN
0x38AA40B7...dDBBEB3fc
0 ETH0.000103791.10000001
Update Flip Supp...106545332024-03-09 5:36:3641 days ago1709962596IN
0x38AA40B7...dDBBEB3fc
0 ETH0.004717250
Fund State Chain...106503542024-03-08 6:03:2442 days ago1709877804IN
0x38AA40B7...dDBBEB3fc
0 ETH0.000063981.25000001
Update Flip Supp...106502212024-03-08 5:22:2442 days ago1709875344IN
0x38AA40B7...dDBBEB3fc
0 ETH0.000141531.5
Update Flip Supp...106458202024-03-07 5:09:2443 days ago1709788164IN
0x38AA40B7...dDBBEB3fc
0 ETH0.000094331.000001
Update Flip Supp...106416022024-03-06 6:23:3644 days ago1709706216IN
0x38AA40B7...dDBBEB3fc
0 ETH0.000000080.002
Update Flip Supp...106415022024-03-06 5:45:3644 days ago1709703936IN
0x38AA40B7...dDBBEB3fc
0 ETH0.000000080.002
Update Flip Supp...106414622024-03-06 5:32:2444 days ago1709703144IN
0x38AA40B7...dDBBEB3fc
0 ETH0.000000080.002
Update Flip Supp...106414342024-03-06 5:19:4844 days ago1709702388IN
0x38AA40B7...dDBBEB3fc
0 ETH0.000000080.002
Update Flip Supp...106413792024-03-06 5:00:3644 days ago1709701236IN
0x38AA40B7...dDBBEB3fc
0 ETH0.000000080.002
Update Flip Supp...106413452024-03-06 4:49:0044 days ago1709700540IN
0x38AA40B7...dDBBEB3fc
0 ETH0.000000180.002
Update Flip Supp...106366512024-03-05 4:40:1245 days ago1709613612IN
0x38AA40B7...dDBBEB3fc
0 ETH0.000141511.5
Fund State Chain...106360392024-03-05 1:11:4845 days ago1709601108IN
0x38AA40B7...dDBBEB3fc
0 ETH0.000076811.5
Update Flip Supp...106320732024-03-04 4:25:4846 days ago1709526348IN
0x38AA40B7...dDBBEB3fc
0 ETH0.000117941.25
Update Flip Supp...106270892024-03-03 4:13:2447 days ago1709439204IN
0x38AA40B7...dDBBEB3fc
0 ETH0.000117931.25
Update Flip Supp...106220112024-03-02 3:51:3648 days ago1709351496IN
0x38AA40B7...dDBBEB3fc
0 ETH0.000141511.5
Update Flip Supp...106169592024-03-01 3:49:2449 days ago1709264964IN
0x38AA40B7...dDBBEB3fc
0 ETH0.000117931.25
Fund State Chain...106130082024-02-29 9:00:3650 days ago1709197236IN
0x38AA40B7...dDBBEB3fc
0 ETH0.000062411.50000001
Fund State Chain...106129812024-02-29 8:52:1250 days ago1709196732IN
0x38AA40B7...dDBBEB3fc
0 ETH0.000069581.5
Update Flip Supp...106118352024-02-29 3:16:4850 days ago1709176608IN
0x38AA40B7...dDBBEB3fc
0 ETH0.000094351
Update Flip Supp...106069152024-02-28 3:14:0051 days ago1709090040IN
0x38AA40B7...dDBBEB3fc
0 ETH0.000141511.5
View all transactions

Latest 25 internal transactions (View All)

Advanced mode:
Parent Transaction Hash Block From To Value
106639792024-03-13 6:20:1237 days ago1710310812
0x38AA40B7...dDBBEB3fc
0 ETH
106639792024-03-13 6:20:1237 days ago1710310812
0x38AA40B7...dDBBEB3fc
0 ETH
106639792024-03-13 6:20:1237 days ago1710310812
0x38AA40B7...dDBBEB3fc
0 ETH
106630352024-03-12 13:13:2438 days ago1710249204
0x38AA40B7...dDBBEB3fc
0 ETH
106625252024-03-12 6:05:1238 days ago1710223512
0x38AA40B7...dDBBEB3fc
0 ETH
106625252024-03-12 6:05:1238 days ago1710223512
0x38AA40B7...dDBBEB3fc
0 ETH
106625252024-03-12 6:05:1238 days ago1710223512
0x38AA40B7...dDBBEB3fc
0 ETH
106607242024-03-11 5:56:3639 days ago1710136596
0x38AA40B7...dDBBEB3fc
0 ETH
106607242024-03-11 5:56:3639 days ago1710136596
0x38AA40B7...dDBBEB3fc
0 ETH
106607242024-03-11 5:56:3639 days ago1710136596
0x38AA40B7...dDBBEB3fc
0 ETH
106583972024-03-10 5:44:1240 days ago1710049452
0x38AA40B7...dDBBEB3fc
0 ETH
106583972024-03-10 5:44:1240 days ago1710049452
0x38AA40B7...dDBBEB3fc
0 ETH
106583972024-03-10 5:44:1240 days ago1710049452
0x38AA40B7...dDBBEB3fc
0 ETH
106545332024-03-09 5:36:3641 days ago1709962596
0x38AA40B7...dDBBEB3fc
0 ETH
106545332024-03-09 5:36:3641 days ago1709962596
0x38AA40B7...dDBBEB3fc
0 ETH
106545332024-03-09 5:36:3641 days ago1709962596
0x38AA40B7...dDBBEB3fc
0 ETH
106503542024-03-08 6:03:2442 days ago1709877804
0x38AA40B7...dDBBEB3fc
0 ETH
106502212024-03-08 5:22:2442 days ago1709875344
0x38AA40B7...dDBBEB3fc
0 ETH
106502212024-03-08 5:22:2442 days ago1709875344
0x38AA40B7...dDBBEB3fc
0 ETH
106502212024-03-08 5:22:2442 days ago1709875344
0x38AA40B7...dDBBEB3fc
0 ETH
106458202024-03-07 5:09:2443 days ago1709788164
0x38AA40B7...dDBBEB3fc
0 ETH
106458202024-03-07 5:09:2443 days ago1709788164
0x38AA40B7...dDBBEB3fc
0 ETH
106458202024-03-07 5:09:2443 days ago1709788164
0x38AA40B7...dDBBEB3fc
0 ETH
106416022024-03-06 6:23:3644 days ago1709706216
0x38AA40B7...dDBBEB3fc
0 ETH
106415022024-03-06 5:45:3644 days ago1709703936
0x38AA40B7...dDBBEB3fc
0 ETH
View All Internal Transactions
Loading...
Loading

Similar Match Source Code
This contract matches the deployed Bytecode of the Source Code for Contract 0xcCC59e2e...831F1600A
The constructor portion of the code might be different and could alter the actual behaviour of the contract

Contract Name:
StateChainGateway

Compiler Version
v0.8.20+commit.a1b79de6

Optimization Enabled:
Yes with 800 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity Standard Json-Input format)

File 1 of 12 : StateChainGateway.sol
// 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;
    }
}

File 3 of 12 : IERC20.sol
// 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);
}

File 4 of 12 : IStateChainGateway.sol
// 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);
}

File 5 of 12 : IFLIP.sol
// 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);
}

File 6 of 12 : IAggKeyNonceConsumer.sol
// 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);
}

File 7 of 12 : IShared.sol
// 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;
    }
}

File 8 of 12 : IKeyManager.sol
// 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);
}

File 9 of 12 : IGovernanceCommunityGuarded.sol
// 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);
}

File 10 of 12 : IFlipIssuer.sol
// 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);
}

File 11 of 12 : AggKeyNonceConsumer.sol
// 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);
        _;
    }
}

File 12 of 12 : Shared.sol
// 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");
        _;
    }
}

File 13 of 12 : GovernanceCommunityGuarded.sol
// 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");
        _;
    }
}

Settings
{
  "evmVersion": "paris",
  "optimizer": {
    "enabled": true,
    "runs": 800
  },
  "libraries": {
    "StateChainGateway.sol": {}
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  }
}

Contract ABI

[{"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"}]

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106101985760003560e01c80634fc07d75116100e3578063aae9ba431161008c578063e6400bbe11610066578063e6400bbe14610438578063e9dddb9c14610440578063fd4e68471461044857600080fd5b8063aae9ba43146102f0578063ab66b98b146102f8578063e62382c3146103fa57600080fd5b806385cac0df116100bd57806385cac0df146102cd5780638d95e559146102d55780639d9f74bd146102dd57600080fd5b80634fc07d75146102a05780636055409b146102a8578063765849b9146102bb57600080fd5b80633f87b30f11610145578063492764931161011f578063492764931461024a5780634b0cfc001461025d5780634e85ba011461026e57600080fd5b80633f87b30f1461021c578063448cfc8514610224578063470887261461023757600080fd5b8063281e54ce11610176578063281e54ce146101e357806329b74201146101f6578063383d3f701461021457600080fd5b8063046f7da21461019d5780631ae8299c146101a75780632351f495146101d1575b600080fd5b6101a561045b565b005b6001546001600160a01b03165b6040516001600160a01b0390911681526020015b60405180910390f35b6004545b6040519081526020016101c8565b6101a56101f136600461246a565b61055f565b600054600160a81b900460ff165b60405190151581526020016101c8565b6101a561080c565b6101b4610baa565b6101a561023236600461246a565b610bb9565b6101a56102453660046124b4565b610d4d565b6101a56102583660046124d8565b610e69565b6000546001600160a01b03166101b4565b61028161027c36600461250c565b6111c0565b604080516001600160a01b0390931683526020830191909152016101c8565b6101b46114b2565b6101a56102b6366004612525565b6114bc565b600054600160a01b900460ff16610204565b6002546101d5565b6101a561166d565b6101a56102eb366004612547565b611777565b6101a5611c2d565b61039a61030636600461250c565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915250600090815260036020908152604091829020825160a0810184528154815260018201546001600160a01b038082169483019490945265ffffffffffff600160a01b8204811695830195909552600160d01b900490931660608401526002015416608082015290565b6040516101c89190600060a0820190508251825260208301516001600160a01b0380821660208501526040850151915065ffffffffffff808316604086015280606087015116606086015250806080860151166080850152505092915050565b6104217f000000000000000000000000000000000000000000000000000000000000007881565b60405165ffffffffffff90911681526020016101c8565b6101a5611d3f565b6101a5611e38565b6101a561045636600461250c565b61202b565b610463612121565b6001600160a01b0316336001600160a01b0316146104c35760405162461bcd60e51b815260206004820152601860248201527723b7bb32b93730b731b29d103737ba1033b7bb32b93737b960411b60448201526064015b60405180910390fd5b600054600160a81b900460ff1661051c5760405162461bcd60e51b815260206004820152601960248201527f476f7665726e616e63653a206e6f742073757370656e6465640000000000000060448201526064016104ba565b6000805460ff60a81b191681556040519081527f58e6c20b68c19f4d8dbc6206267af40b288342464b433205bb41e5b65c4016da906020015b60405180910390a1565b600054600160a81b900460ff16156105b15760405162461bcd60e51b815260206004820152601560248201527411dbdd995c9b985b98d94e881cdd5cdc195b991959605a1b60448201526064016104ba565b816001600160a01b0381166106085760405162461bcd60e51b815260206004820152601e60248201527f5368617265643a206164647265737320696e70757420697320656d707479000060448201526064016104ba565b6040805163140f2a6760e11b60208201526001600160a01b03851691810191909152821515606082015284906080016040516020818303038152906040528051906020012061065f6000546001600160a01b031690565b6001600160a01b0316632cb2b86283836040518363ffffffff1660e01b815260040161068c9291906125c2565b600060405180830381600087803b1580156106a657600080fd5b505af11580156106ba573d6000803e3d6000fd5b505050508361078e57600154604080516306ba0a6760e21b815290516001600160a01b0392831692881691631ae8299c9160048083019260209291908290030181865afa15801561070f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061073391906125fe565b6001600160a01b0316146107895760405162461bcd60e51b815260206004820152601760248201527f476174657761793a2077726f6e6720464c49502072656600000000000000000060448201526064016104ba565b6107a5565b6000856001600160a01b03163b116107a557600080fd5b600154604051637831243560e01b81526001600160a01b03878116600483015290911690637831243590602401600060405180830381600087803b1580156107ec57600080fd5b505af1158015610800573d6000803e3d6000fd5b50505050505050505050565b610814612121565b6001600160a01b0316336001600160a01b03161461086f5760405162461bcd60e51b815260206004820152601860248201527723b7bb32b93730b731b29d103737ba1033b7bb32b93737b960411b60448201526064016104ba565b600054600160a01b900460ff166108d45760405162461bcd60e51b815260206004820152602360248201527f476f7665726e616e63653a20636f6d6d756e69747920677561726420656e61626044820152621b195960ea1b60648201526084016104ba565b600054600160a81b900460ff1661092d5760405162461bcd60e51b815260206004820152601960248201527f476f7665726e616e63653a206e6f742073757370656e6465640000000000000060448201526064016104ba565b6001546040516370a0823160e01b81523060048201526001600160a01b039091169060009082906370a0823190602401602060405180830381865afa15801561097a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061099e919061261b565b905060006109b46000546001600160a01b031690565b6001600160a01b031663cd1b4d206040518163ffffffff1660e01b8152600401602060405180830381865afa1580156109f1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a1591906125fe565b60405163a9059cbb60e01b81526001600160a01b038083166004830152602482018590529192509084169063a9059cbb906044016020604051808303816000875af1158015610a68573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a8c9190612634565b50604080516001600160a01b0383168152602081018490527ffb698a1f0614fe8250cab73f9e958d9eb3aa668918f243f3638dba6da247643d910160405180910390a1306001600160a01b0316836001600160a01b031663525564216040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b17573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b3b91906125fe565b6001600160a01b031603610ba557604051637831243560e01b81526001600160a01b038281166004830152841690637831243590602401600060405180830381600087803b158015610b8c57600080fd5b505af1158015610ba0573d6000803e3d6000fd5b505050505b505050565b6000610bb461218f565b905090565b816001600160a01b038116610c105760405162461bcd60e51b815260206004820152601e60248201527f5368617265643a206164647265737320696e70757420697320656d707479000060448201526064016104ba565b6040805163448cfc8560e01b60208201526001600160a01b038516918101919091528215156060820152849060800160405160208183030381529060405280519060200120610c676000546001600160a01b031690565b6001600160a01b0316632cb2b86283836040518363ffffffff1660e01b8152600401610c949291906125c2565b600060405180830381600087803b158015610cae57600080fd5b505af1158015610cc2573d6000803e3d6000fd5b505050506000856001600160a01b03163b11610cdd57600080fd5b610ce785856121d9565b6000805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0387169081179091556040519081527fd18040e514983d65f088430e69091aea9bf07feaed3696a3faac1ccc34b5e3bc9060200160405180910390a1505050505050565b806001600160a01b038116610da45760405162461bcd60e51b815260206004820152601e60248201527f5368617265643a206164647265737320696e70757420697320656d707479000060448201526064016104ba565b6001546001600160a01b031615610e075760405162461bcd60e51b815260206004820152602160248201527f476174657761793a20466c6970206164647265737320616c72656164792073656044820152601d60fa1b60648201526084016104ba565b6001805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0384169081179091556040519081527f28a7be5ead6163acf2999fbd7effa68e097435d695eae192ae3121c9b4e502559060200160405180910390a15050565b600054600160a81b900460ff1615610ebb5760405162461bcd60e51b815260206004820152601560248201527411dbdd995c9b985b98d94e881cdd5cdc195b991959605a1b60448201526064016104ba565b8180600003610f0c5760405162461bcd60e51b815260206004820152601b60248201527f5368617265643a2075696e7420696e70757420697320656d707479000000000060448201526064016104ba565b60408051634927649360e01b602082015290810184905260608101839052849060800160405160208183030381529060405280519060200120610f576000546001600160a01b031690565b6001600160a01b0316632cb2b86283836040518363ffffffff1660e01b8152600401610f849291906125c2565b600060405180830381600087803b158015610f9e57600080fd5b505af1158015610fb2573d6000803e3d6000fd5b5050505060045484116110075760405162461bcd60e51b815260206004820152601f60248201527f476174657761793a206f6c6420464c495020737570706c79207570646174650060448201526064016104ba565b6004848155600154604080516318160ddd60e01b815290516001600160a01b039092169260009284926318160ddd92818101926020929091908290030181865afa158015611059573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061107d919061261b565b9050808710156110fc5760006110938883612667565b604051632770a7eb60e21b8152306004820152602481018290529091506001600160a01b03841690639dc29fac90604401600060405180830381600087803b1580156110de57600080fd5b505af11580156110f2573d6000803e3d6000fd5b5050505050611175565b808711156111755760006111108289612667565b6040516340c10f1960e01b8152306004820152602481018290529091506001600160a01b038416906340c10f1990604401600060405180830381600087803b15801561115b57600080fd5b505af115801561116f573d6000803e3d6000fd5b50505050505b60408051828152602081018990529081018790527fff4b7a826623672c6944dc44d809008e2e1105180d110fd63986e841f15eb2ad9060600160405180910390a15050505050505050565b600080548190600160a81b900460ff16156112155760405162461bcd60e51b815260206004820152601560248201527411dbdd995c9b985b98d94e881cdd5cdc195b991959605a1b60448201526064016104ba565b600083815260036020908152604091829020825160a0810184528154815260018201546001600160a01b038082169483019490945265ffffffffffff600160a01b82048116958301869052600160d01b909104166060820152600290910154909116608082015290421080159061129857506000816060015165ffffffffffff16115b6112e45760405162461bcd60e51b815260206004820152601f60248201527f476174657761793a206561726c79206f7220616c72656164792065786563640060448201526064016104ba565b60008481526003602052604081208181556001810191909155600201805473ffffffffffffffffffffffffffffffffffffffff19169055606081015165ffffffffffff16421161146d5760808101516001600160a01b0316156113a65780608001516001600160a01b0316336001600160a01b0316146113a65760405162461bcd60e51b815260206004820152601560248201527f476174657761793a206e6f74206578656375746f72000000000000000000000060448201526064016104ba565b805160405190815284907f2b917410dde505b91c1ee8bf49bc98c4d80f9f6fde62c4aad7743e5c3fcd568f9060200160405180910390a26001546020820151825160405163a9059cbb60e01b81526001600160a01b039283166004820152602481019190915291169063a9059cbb906044016020604051808303816000875af1158015611437573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061145b9190612634565b50602081015190519092509050915091565b805160405190815284907f2e395ce432fa118cf9b801546bae2c36a87aa9b514af0bec0df46bb534513de59060200160405180910390a2602001519360009350915050565b6000610bb4612121565b818061150a5760405162461bcd60e51b815260206004820152601e60248201527f5368617265643a206279746573333220696e70757420697320656d707479000060448201526064016104ba565b6001546001600160a01b0316806115635760405162461bcd60e51b815260206004820152601560248201527f476174657761793a20466c6970206e6f7420736574000000000000000000000060448201526064016104ba565b6002548310156115b55760405162461bcd60e51b815260206004820152601960248201527f476174657761793a206e6f7420656e6f7567682066756e64730000000000000060448201526064016104ba565b6040516323b872dd60e01b8152336004820152306024820152604481018490526001600160a01b038216906323b872dd906064016020604051808303816000875af1158015611608573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061162c9190612634565b506040805184815233602082015285917fc1b5c1b3c1e294059714af16e812402029c9d8bf1d0d89770d3ff069dddc48db910160405180910390a250505050565b61167561218f565b6001600160a01b0316336001600160a01b0316146116d55760405162461bcd60e51b815260206004820152601d60248201527f476f7665726e616e63653a206e6f7420436f6d6d756e697479204b657900000060448201526064016104ba565b600054600160a01b900460ff1661173a5760405162461bcd60e51b815260206004820152602360248201527f476f7665726e616e63653a20636f6d6d756e69747920677561726420656e61626044820152621b195960ea1b60648201526084016104ba565b6000805460ff60a01b191681556040519081527f057c4cb09f128960151f04372028154acda40272f16360154961672989b59bad90602001610555565b600054600160a81b900460ff16156117c95760405162461bcd60e51b815260206004820152601560248201527411dbdd995c9b985b98d94e881cdd5cdc195b991959605a1b60448201526064016104ba565b84806118175760405162461bcd60e51b815260206004820152601e60248201527f5368617265643a206279746573333220696e70757420697320656d707479000060448201526064016104ba565b84806000036118685760405162461bcd60e51b815260206004820152601b60248201527f5368617265643a2075696e7420696e70757420697320656d707479000000000060448201526064016104ba565b846001600160a01b0381166118bf5760405162461bcd60e51b815260206004820152601e60248201527f5368617265643a206164647265737320696e70757420697320656d707479000060448201526064016104ba565b60408051639d9f74bd60e01b6020820152908101899052606081018890526001600160a01b03808816608083015265ffffffffffff871660a0830152851660c0820152899060e0016040516020818303038152906040528051906020012061192f6000546001600160a01b031690565b6001600160a01b0316632cb2b86283836040518363ffffffff1660e01b815260040161195c9291906125c2565b600060405180830381600087803b15801561197657600080fd5b505af115801561198a573d6000803e3d6000fd5b50505060008b815260036020526040902060010154600160d01b900465ffffffffffff1642119050611a0a5760405162461bcd60e51b8152602060048201526024808201527f476174657761793a20612070656e64696e6720726564656d7074696f6e2065786044820152636973747360e01b60648201526084016104ba565b6000611a367f000000000000000000000000000000000000000000000000000000000000007842612680565b90508065ffffffffffff168865ffffffffffff1611611a975760405162461bcd60e51b815260206004820152601d60248201527f476174657761793a206578706972792074696d6520746f6f20736f6f6e00000060448201526064016104ba565b6040518060a001604052808b81526020018a6001600160a01b031681526020018265ffffffffffff1681526020018965ffffffffffff168152602001886001600160a01b0316815250600360008d81526020019081526020016000206000820151816000015560208201518160010160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060408201518160010160146101000a81548165ffffffffffff021916908365ffffffffffff160217905550606082015181600101601a6101000a81548165ffffffffffff021916908365ffffffffffff16021790555060808201518160020160006101000a8154816001600160a01b0302191690836001600160a01b03160217905550905050886001600160a01b03168b7e595d7bd66cc5e1bac8c1f380818b52987790a5b3b3cbc753a7945469be2cd88c848c8c604051611c17949392919093845265ffffffffffff9283166020850152911660408301526001600160a01b0316606082015260800190565b60405180910390a3505050505050505050505050565b611c3561218f565b6001600160a01b0316336001600160a01b031614611c955760405162461bcd60e51b815260206004820152601d60248201527f476f7665726e616e63653a206e6f7420436f6d6d756e697479204b657900000060448201526064016104ba565b600054600160a01b900460ff1615611cfb5760405162461bcd60e51b8152602060048201526024808201527f476f7665726e616e63653a20636f6d6d756e6974792067756172642064697361604482015263189b195960e21b60648201526084016104ba565b6000805460ff60a01b1916600160a01b179055604051600181527f057c4cb09f128960151f04372028154acda40272f16360154961672989b59bad90602001610555565b611d47612121565b6001600160a01b0316336001600160a01b031614611da25760405162461bcd60e51b815260206004820152601860248201527723b7bb32b93730b731b29d103737ba1033b7bb32b93737b960411b60448201526064016104ba565b600054600160a81b900460ff1615611df45760405162461bcd60e51b815260206004820152601560248201527411dbdd995c9b985b98d94e881cdd5cdc195b991959605a1b60448201526064016104ba565b6000805460ff60a81b1916600160a81b179055604051600181527f58e6c20b68c19f4d8dbc6206267af40b288342464b433205bb41e5b65c4016da90602001610555565b611e40612121565b6001600160a01b0316336001600160a01b031614611e9b5760405162461bcd60e51b815260206004820152601860248201527723b7bb32b93730b731b29d103737ba1033b7bb32b93737b960411b60448201526064016104ba565b600054600160a01b900460ff16611f005760405162461bcd60e51b815260206004820152602360248201527f476f7665726e616e63653a20636f6d6d756e69747920677561726420656e61626044820152621b195960ea1b60648201526084016104ba565b600054600160a81b900460ff16611f595760405162461bcd60e51b815260206004820152601960248201527f476f7665726e616e63653a206e6f742073757370656e6465640000000000000060448201526064016104ba565b600080546001600160a01b03166001600160a01b031663cd1b4d206040518163ffffffff1660e01b8152600401602060405180830381865afa158015611fa3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fc791906125fe565b600154604051637831243560e01b81526001600160a01b038084166004830152929350911690637831243590602401600060405180830381600087803b15801561201057600080fd5b505af1158015612024573d6000803e3d6000fd5b5050505050565b808060000361207c5760405162461bcd60e51b815260206004820152601b60248201527f5368617265643a2075696e7420696e70757420697320656d707479000000000060448201526064016104ba565b612084612121565b6001600160a01b0316336001600160a01b0316146120df5760405162461bcd60e51b815260206004820152601860248201527723b7bb32b93730b731b29d103737ba1033b7bb32b93737b960411b60448201526064016104ba565b60025460408051918252602082018490527f09c1d94393b22192a9e1fc232a9accb31e0c1ad78f42b2f42f9da84e9931d16d910160405180910390a150600255565b600080546001600160a01b03166001600160a01b031663cd1b4d206040518163ffffffff1660e01b8152600401602060405180830381865afa15801561216b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bb491906125fe565b600080546001600160a01b03166001600160a01b0316633f87b30f6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561216b573d6000803e3d6000fd5b6000826001600160a01b031663cd1b4d206040518163ffffffff1660e01b8152600401602060405180830381865afa158015612219573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061223d91906125fe565b90506000836001600160a01b0316633f87b30f6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561227f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122a391906125fe565b9050826123fd576122b2612121565b6001600160a01b0316826001600160a01b03161480156122ea57506122d561218f565b6001600160a01b0316816001600160a01b0316145b6122f357600080fd5b6000846001600160a01b031663d5b9c0366040518163ffffffff1660e01b81526004016040805180830381865afa158015612332573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061235691906126a6565b9050600061236c6000546001600160a01b031690565b6001600160a01b031663d5b9c0366040518163ffffffff1660e01b81526004016040805180830381865afa1580156123a8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123cc91906126a6565b805183519192501480156123ed5750806020015160ff16826020015160ff16145b6123f657600080fd5b5050612426565b6001600160a01b0382161580159061241d57506001600160a01b03811615155b61242657600080fd5b50505050565b60006060828403121561243e57600080fd5b50919050565b6001600160a01b038116811461245957600080fd5b50565b801515811461245957600080fd5b600080600060a0848603121561247f57600080fd5b612489858561242c565b9250606084013561249981612444565b915060808401356124a98161245c565b809150509250925092565b6000602082840312156124c657600080fd5b81356124d181612444565b9392505050565b600080600060a084860312156124ed57600080fd5b6124f7858561242c565b95606085013595506080909401359392505050565b60006020828403121561251e57600080fd5b5035919050565b6000806040838503121561253857600080fd5b50508035926020909101359150565b600080600080600080610100878903121561256157600080fd5b61256b888861242c565b9550606087013594506080870135935060a087013561258981612444565b925060c087013565ffffffffffff811681146125a457600080fd5b915060e08701356125b481612444565b809150509295509295509295565b82358152602080840135908201526080810160408401356125e281612444565b6001600160a01b03166040830152606090910191909152919050565b60006020828403121561261057600080fd5b81516124d181612444565b60006020828403121561262d57600080fd5b5051919050565b60006020828403121561264657600080fd5b81516124d18161245c565b634e487b7160e01b600052601160045260246000fd5b8181038181111561267a5761267a612651565b92915050565b65ffffffffffff81811683821601908082111561269f5761269f612651565b5092915050565b6000604082840312156126b857600080fd5b6040516040810181811067ffffffffffffffff821117156126e957634e487b7160e01b600052604160045260246000fd5b60405282518152602083015160ff8116811461270457600080fd5b6020820152939250505056fea264697066735822122074762e1f49f40fa09b7b96be9157adb83d1b428abbe8b3985abd9ac21eb390fc64736f6c63430008140033

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
[ 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.