ETH Price: $2,525.96 (+0.28%)

Contract

0xd5970622b740a2eA5A5574616c193968b10e1297
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Token Holdings

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Claim Holding Si...206436012024-08-30 19:51:598 hrs ago1725047519IN
0xd5970622...8b10e1297
0 ETH0.000078891.63420217
Claim Holding Si...206385732024-08-30 3:01:2325 hrs ago1724986883IN
0xd5970622...8b10e1297
0 ETH0.000078561.20170274
Claim Holding Si...206300192024-08-28 22:18:112 days ago1724883491IN
0xd5970622...8b10e1297
0 ETH0.000103552.1451394
Claim Holding Si...206168552024-08-27 2:11:114 days ago1724724671IN
0xd5970622...8b10e1297
0 ETH0.000039960.8283391
Claim Holding Si...206164522024-08-27 0:50:114 days ago1724719811IN
0xd5970622...8b10e1297
0 ETH0.000077051.59619122
Claim Holding Si...206163252024-08-27 0:24:474 days ago1724718287IN
0xd5970622...8b10e1297
0 ETH0.000030610.68557613
Claim Holding Si...206163222024-08-27 0:24:114 days ago1724718251IN
0xd5970622...8b10e1297
0 ETH0.000039240.81291717
Claim Holding Si...206135452024-08-26 15:05:114 days ago1724684711IN
0xd5970622...8b10e1297
0 ETH0.000340985.21666985
Claim Holding Si...206106702024-08-26 5:26:594 days ago1724650019IN
0xd5970622...8b10e1297
0 ETH0.000051560.78879672
Claim Holding Si...206106652024-08-26 5:25:594 days ago1724649959IN
0xd5970622...8b10e1297
0 ETH0.000053420.81725622
Claim Holding Si...206077332024-08-25 19:36:355 days ago1724614595IN
0xd5970622...8b10e1297
0 ETH0.000065521.0022914
Claim Holding Si...205984952024-08-24 12:35:476 days ago1724502947IN
0xd5970622...8b10e1297
0 ETH0.000061931.2828807
Claim Holding Si...205984862024-08-24 12:33:596 days ago1724502839IN
0xd5970622...8b10e1297
0 ETH0.000062771.30036375
Claim Holding Si...205791622024-08-21 19:44:119 days ago1724269451IN
0xd5970622...8b10e1297
0 ETH0.000097522.02008362
Claim Holding Si...205663502024-08-20 0:47:3511 days ago1724114855IN
0xd5970622...8b10e1297
0 ETH0.000106022.19625773
Claim Holding Si...205641112024-08-19 17:18:1111 days ago1724087891IN
0xd5970622...8b10e1297
0 ETH0.000179352.74338801
Claim Holding Si...205639602024-08-19 16:47:3511 days ago1724086055IN
0xd5970622...8b10e1297
0 ETH0.000107192.22045961
Claim Holding Si...205571722024-08-18 18:01:4712 days ago1724004107IN
0xd5970622...8b10e1297
0 ETH0.000122261.87015583
Claim Holding Si...205570632024-08-18 17:39:5912 days ago1724002799IN
0xd5970622...8b10e1297
0 ETH0.000168042.57045433
Claim Holding Si...205372112024-08-15 23:09:3515 days ago1723763375IN
0xd5970622...8b10e1297
0 ETH0.000229824.76074796
Claim Holding Si...205371972024-08-15 23:06:3515 days ago1723763195IN
0xd5970622...8b10e1297
0 ETH0.00023714.91141187
Claim Holding Si...205320992024-08-15 5:59:4715 days ago1723701587IN
0xd5970622...8b10e1297
0 ETH0.000112452.32932525
Claim Holding Si...205203362024-08-13 14:35:3517 days ago1723559735IN
0xd5970622...8b10e1297
0 ETH0.000205384.25651538
Claim Holding Si...204871812024-08-08 23:32:5922 days ago1723159979IN
0xd5970622...8b10e1297
0 ETH0.000259765.38078086
Claim Holding Si...204850902024-08-08 16:33:4722 days ago1723134827IN
0xd5970622...8b10e1297
0 ETH0.0010175521.07792557
View all transactions

View more zero value Internal Transactions in Advanced View mode

Advanced mode:
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
SafetyDelay

Compiler Version
v0.8.21+commit.d9974bed

Optimization Enabled:
Yes with 1000000 runs

Other Settings:
paris EvmVersion
File 1 of 6 : SafetyDelay.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

import {IVetoCouncil} from "@/interfaces/IVetoCouncil.sol";
import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";

/**
 * @dev Struct representing a holding of tokens in the HoldingContract.
 * @param amount The amount of tokens being held.
 * @param expirationTimestamp The timestamp at which the holding expires and can be withdrawn.
 */
struct Holding {
    uint192 amount;
    uint64 expirationTimestamp;
}

/**
 * @dev a helper type to organize claim holdings arguments
 * @param user the address of the user
 * @param token the address of the USDC token to withdraw
 */
struct ClaimHoldingArgs {
    address user;
    address token;
}

interface ISafetyDelay {
    function addHolding(address user, address token, uint192 amount) external;
    function holdings(address user, address token) external view returns (Holding memory);
    function claimHoldings(ClaimHoldingArgs[] memory args) external;
}

/**
 * @title SafetyDelay
 * @notice This contract is used to hold tokens for users
 *         - This contract holds all USDC tokens that are part of the protocol
 *         - Once farms withdraw, there is a 1 week delay before they can claim their tokens
 *         - The Miner Pool Contract assigns these holdings as part of the withdraw process
 *         - Veto Agents can delay all withdrawals by 13 weeks
 *         - A holding can be max delayed for 97 days
 */
contract SafetyDelay is ISafetyDelay {
    /* -------------------------------------------------------------------------- */
    /*                                   errors                                   */
    /* -------------------------------------------------------------------------- */
    error OnlyMinerPoolCanAddHoldings();
    error WithdrawalNotReady();
    error CallerMustBeVetoCouncilMember();
    error DelayStillOnCooldown();
    error NetworkIsFrozen();
    error AlreadyWithdrawnFromHolding();
    error MinerPoolAlreadySet();

    /* -------------------------------------------------------------------------- */
    /*                                  constants                                 */
    /* -------------------------------------------------------------------------- */
    /**
     * @notice the default delay for withdrawals
     * @dev the default delay is 7 days
     * Whenever a user withdraws from the miner pool,
     *       their funds are locked for 7 days
     */
    uint256 public constant DEFAULT_DELAY = uint256(7 days);

    /**
     * @dev 90 days in seconds
     */
    uint256 public constant NINETY_DAYS = uint256(90 days);

    /**
     * @notice the delay for withdrawals after the network is delayed
     * @dev the delay is 13 weeks
     * all withdrawals will be delayed for 13 weeks
     */
    uint256 public constant VETO_HOLDING_DELAY = uint256(13 weeks);

    /**
     * @dev a cached version of five weeks in seconds
     * @dev used in delayNetwork to ensure that the network can only be delayed every 5 weeks
     * @dev This helps prevent bad veto agents from spamming the delay network function
     *         - by giving governance enough time to kick out the veto agent
     */
    uint256 public constant FIVE_WEEKS = uint256(5 weeks);

    /* -------------------------------------------------------------e------------- */
    /*                                 immutables                                 */
    /* -------------------------------------------------------------------------- */
    /**
     * @notice the address of the veto council
     * @dev veto council members can delay the network
     */
    IVetoCouncil public immutable VETO_COUNCIL;

    /**
     * @notice the address of the miner pool
     * @dev this is the address that can add holdings to the contract
     */
    address public immutable MINER_POOL;

    /* -------------------------------------------------------------------------- */
    /*                                 state vars                                */
    /* -------------------------------------------------------------------------- */

    /**
     * @notice the minimum timestamp for withdrawals
     * @dev any claims below this timestamp will revert
     */
    uint256 public minimumWithdrawTimestamp;

    /* -------------------------------------------------------------------------- */
    /*                                   mappings                                  */
    /* -------------------------------------------------------------------------- */
    /**
     * @notice the holdings for each user
     *     Note: We could have chosen an array of holdings
     *     such that each withdraw truly is a FIFO queue with 1 week delay
     *     However, we chose to store all holdings in a single slot
     *     to avoid cold sstores and sloads
     *     The downside of this approach is that we can't have a FIFO queue
     *     and that any time a withdraw is made from the miner pool contract
     *     the user's holdings are locked for 7 days
     */
    mapping(address => mapping(address => Holding)) private _holdings;

    /* -------------------------------------------------------------------------- */
    /*                                   events                                  */
    /* -------------------------------------------------------------------------- */
    /**
     * @dev emitted when there is a network delay
     * @param vetoAgent the address of the veto agent that delayed the network
     * @param timestamp the timestamp at which the network was delayed
     */
    event NetworkDelay(address vetoAgent, uint256 timestamp);

    /**
     * @dev emitted whenever a holding is added to a user
     * @param user the address of the user
     * @param token the address of the USDC token
     * @param amount the amount of tokens added to the holding
     * @dev we dont emit a {HoldingClaimed} event since there may be a tax
     *     - on the token that will mess up the data.
     *     - we rely on catching transfer events
     */
    event HoldingAdded(address indexed user, address indexed token, uint192 amount);

    /*
        * @notice emitted when a user claims their holding
        * @param user the address of the user
        * @param token the address of the USDC token
        * @param amount the amount of tokens claimed
    */
    event HoldingClaimed(address indexed user, address indexed token, uint192 amount);

    /* -------------------------------------------------------------------------- */
    /*                                 constructor                                */
    /* -------------------------------------------------------------------------- */

    /**
     * @param _vetoCouncil the address of the veto council
     * @param _minerPool the address of the miner pool
     */
    constructor(address _vetoCouncil, address _minerPool) payable {
        VETO_COUNCIL = IVetoCouncil(_vetoCouncil);
        MINER_POOL = _minerPool;
    }

    /* -------------------------------------------------------------------------- */
    /*                                    delay                                   */
    /* -------------------------------------------------------------------------- */

    /**
     * @notice allows veto council members to delay the network by 13 weeks
     */
    function delayNetwork() external {
        if (!VETO_COUNCIL.isCouncilMember(msg.sender)) {
            _revert(CallerMustBeVetoCouncilMember.selector);
        }
        uint256 _minimumWithdrawTimestamp = minimumWithdrawTimestamp;
        if (_minimumWithdrawTimestamp == 0) {
            minimumWithdrawTimestamp = block.timestamp + VETO_HOLDING_DELAY;
            emit NetworkDelay(msg.sender, block.timestamp);
            return;
        }
        if (block.timestamp < _minimumWithdrawTimestamp) {
            //The block.timestamp needs to be within 5 weeks of
            //minimumWithdrawTimestamp
            uint256 timeLeftInDelay = _minimumWithdrawTimestamp - block.timestamp;
            if (timeLeftInDelay > FIVE_WEEKS) {
                _revert(DelayStillOnCooldown.selector);
            }
        }

        minimumWithdrawTimestamp = block.timestamp + VETO_HOLDING_DELAY;
        emit NetworkDelay(msg.sender, block.timestamp);
    }

    /* -------------------------------------------------------------------------- */
    /*                                   claim                                    */
    /* -------------------------------------------------------------------------- */

    /**
     * @notice entrypoint to claim holdings
     * @param args - an array of {ClaimHoldingArgs}
     * @dev this is a batch method to claim holdings
     *     - this is more gas efficient than calling claimHolding for each holding
     *     - the protocol may use a relayer to bundle claims
     */
    function claimHoldings(ClaimHoldingArgs[] memory args) external {
        //If the network is frozen, don't allow withdrawals
        bool networkIsFrozen = isNetworkFrozen();
        //Loop over all the arguments
        uint256 len = args.length;
        for (uint256 i; i < len;) {
            ClaimHoldingArgs memory arg = args[i];
            _claimHolding(arg.user, arg.token, networkIsFrozen);
            unchecked {
                ++i;
            }
        }
    }

    /**
     * @notice entrypoint to claim a single holding
     * @param user the address of the user
     * @param token the address of the USDC token to withdraw
     * @dev should be used if the user only wants to claim their holding
     */
    function claimHoldingSingleton(address user, address token) external {
        // If the network is frozen and timestamp since expiration is not more than 90 days, don't allow withdrawals
        bool networkIsFrozen = isNetworkFrozen();
        _claimHolding(user, token, networkIsFrozen);
    }

    /* -------------------------------------------------------------------------- */
    /*                                 add holdings                               */
    /* -------------------------------------------------------------------------- */

    /**
     * @notice an internal method to increment the amount in a holding
     * @param user the address of the user
     * @param token the address of the USDC token to withdraw
     * @param amount the amount of tokens to add to the holding
     */
    function addHolding(address user, address token, uint192 amount) external {
        if (msg.sender != MINER_POOL) {
            _revert(OnlyMinerPoolCanAddHoldings.selector);
        }
        _holdings[user][token].amount += amount;
        _holdings[user][token].expirationTimestamp = uint64(block.timestamp + DEFAULT_DELAY);
        emit HoldingAdded(user, token, amount);
    }

    /* -------------------------------------------------------------------------- */
    /*                                 view functions                             */
    /* -------------------------------------------------------------------------- */
    /**
     * @notice returns the Holding struct for a user and token pair
     * @param user the address of the user
     * @param token the address of the USDC token to withdraw
     * @return holding - the Holding struct
     */
    function holdings(address user, address token) external view returns (Holding memory) {
        return _holdings[user][token];
    }

    /**
     * @notice returns true if the network is frozen
     * @dev the network is frozen if the minimumWithdrawTimestamp is greater than the current block timestamp
     * @return isNetworkFrozen - true if the network is frozen
     */
    function isNetworkFrozen() public view returns (bool) {
        return block.timestamp < minimumWithdrawTimestamp;
    }

    /**
     * @dev checks if the holding is available to be withdrawn
     * @param holdingExpirationTimestamp the timestamp at which the holding expires
     * @param isNetworkFrozen whether or not the network is currently frozen
     * @dev - if the network is frozen, the holding can be withdrawn only if it's been more than 90 days past the expiration of the holding
     *      - if the network is not frozen, the holding can be withdrawn only if it's past the expiration date of the holding
     */
    function checkHoldingAvailable(uint64 holdingExpirationTimestamp, bool isNetworkFrozen) internal view {
        if (block.timestamp < holdingExpirationTimestamp) {
            _revert(WithdrawalNotReady.selector);
        }
        //Can't underflow because of the check above
        //No claim should be able to be held for more than 97 days
        //If it's been less than than 97 days since the proposal has expired,
        //(expiration timestamp is always claim timestamp + 1 week, so )
        //in order for proposal to be held maximum 97 days,
        //We need to check if the diff is 90 days
        if (block.timestamp - holdingExpirationTimestamp < NINETY_DAYS) {
            if (isNetworkFrozen) {
                _revert(NetworkIsFrozen.selector);
            }
        }
    }

    /* -------------------------------------------------------------------------- */
    /*                                   utils                                    */
    /* -------------------------------------------------------------------------- */

    /**
     * @dev an internal method to claim a holding
     * @param user the address of the user
     * @param token the address of the USDC token to withdraw
     * @param networkIsFrozen whether or not the network is currently frozen
     */
    function _claimHolding(address user, address token, bool networkIsFrozen) internal {
        Holding memory holding = _holdings[user][token];
        checkHoldingAvailable(holding.expirationTimestamp, networkIsFrozen);
        //Delete the holding args.
        //Should set all the data to zero.
        delete _holdings[user][token];
        //Add the amount to the amount to transfer
        SafeERC20.safeTransfer(IERC20(token), user, holding.amount);
        emit HoldingClaimed(user, token, holding.amount);
    }

    /**
     * @dev more efficient reverts
     * @param selector the selector of the error
     */

    function _revert(bytes4 selector) internal pure {
        // solhint-disable-next-line no-inline-assembly
        assembly {
            mstore(0, selector)
            revert(0, 4)
        }
    }
}

File 2 of 6 : IVetoCouncil.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

interface IVetoCouncil {
    /* -------------------------------------------------------------------------- */
    /*                                   errors                                    */
    /* -------------------------------------------------------------------------- */
    error CallerNotGovernance();
    error NoRewards();
    error ZeroAddressInConstructor();
    error MaxCouncilMembersExceeded();

    /* -------------------------------------------------------------------------- */
    /*                                   events                                    */
    /* -------------------------------------------------------------------------- */

    /**
     * @param oldMember The address of the member to be slashed or removed
     * @param newMember The address of the new member (0 = no new member)
     * @param slashOldMember Whether to slash the member or not
     */
    event VetoCouncilSeatsEdited(address indexed oldMember, address indexed newMember, bool slashOldMember);

    /**
     * @dev emitted when a council member is paid out
     * @param account The address of the council member
     * @param amountNow The amount paid out now
     * @param amountToBeVested The amount to be vested
     */
    event CouncilMemberPayout(address indexed account, uint256 amountNow, uint256 amountToBeVested);
    /* -------------------------------------------------------------------------- */
    /*                                 state-changing                             */
    /* -------------------------------------------------------------------------- */
    /**
     * @notice Add or remove a council member
     * @param oldMember The address of the member to be slashed or removed
     * @param newMember The address of the new member (0 = no new member)
     * @param slashOldMember Whether to slash the member or not
     * @return - true if the council member was added or removed, false if nothing was done
     *                 - the function should return false if the new member is already a council member
     *                 - if the old member is not a council member, the function should return false
     *                 - if the old member is a council member and the new member is the same as the old member, the function should return false
     *                 - by adding a new member there would be more than 7 council members, the function should return false
     */

    function addAndRemoveCouncilMember(address oldMember, address newMember, bool slashOldMember)
        external
        returns (bool);

    /**
     * @notice Payout the council member
     * @param member The address of the council member
     * @param nonce The payout nonce to claim from
     * @param sync Whether to sync the vesting schedule or not
     * @param members The addresses of the council members that were active at `nonce`
     */
    function claimPayout(address member, uint256 nonce, bool sync, address[] memory members) external;

    /* -------------------------------------------------------------------------- */
    /*                                   view                                    */
    /* -------------------------------------------------------------------------- */
    /**
     * @notice returns true if the member is a council member
     * @param member The address of the member to be checked
     * @return - true if the member is a council member
     */
    function isCouncilMember(address member) external view returns (bool);
}

File 3 of 6 : SafeERC20.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/utils/SafeERC20.sol)

pragma solidity ^0.8.20;

import {IERC20} from "../IERC20.sol";
import {IERC20Permit} from "../extensions/IERC20Permit.sol";
import {Address} from "../../../utils/Address.sol";

/**
 * @title SafeERC20
 * @dev Wrappers around ERC20 operations that throw on failure (when the token
 * contract returns false). Tokens that return no value (and instead revert or
 * throw on failure) are also supported, non-reverting calls are assumed to be
 * successful.
 * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
 * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
 */
library SafeERC20 {
    using Address for address;

    /**
     * @dev An operation with an ERC20 token failed.
     */
    error SafeERC20FailedOperation(address token);

    /**
     * @dev Indicates a failed `decreaseAllowance` request.
     */
    error SafeERC20FailedDecreaseAllowance(address spender, uint256 currentAllowance, uint256 requestedDecrease);

    /**
     * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,
     * non-reverting calls are assumed to be successful.
     */
    function safeTransfer(IERC20 token, address to, uint256 value) internal {
        _callOptionalReturn(token, abi.encodeCall(token.transfer, (to, value)));
    }

    /**
     * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the
     * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.
     */
    function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
        _callOptionalReturn(token, abi.encodeCall(token.transferFrom, (from, to, value)));
    }

    /**
     * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,
     * non-reverting calls are assumed to be successful.
     */
    function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
        uint256 oldAllowance = token.allowance(address(this), spender);
        forceApprove(token, spender, oldAllowance + value);
    }

    /**
     * @dev Decrease the calling contract's allowance toward `spender` by `requestedDecrease`. If `token` returns no value,
     * non-reverting calls are assumed to be successful.
     */
    function safeDecreaseAllowance(IERC20 token, address spender, uint256 requestedDecrease) internal {
        unchecked {
            uint256 currentAllowance = token.allowance(address(this), spender);
            if (currentAllowance < requestedDecrease) {
                revert SafeERC20FailedDecreaseAllowance(spender, currentAllowance, requestedDecrease);
            }
            forceApprove(token, spender, currentAllowance - requestedDecrease);
        }
    }

    /**
     * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,
     * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval
     * to be set to zero before setting it to a non-zero value, such as USDT.
     */
    function forceApprove(IERC20 token, address spender, uint256 value) internal {
        bytes memory approvalCall = abi.encodeCall(token.approve, (spender, value));

        if (!_callOptionalReturnBool(token, approvalCall)) {
            _callOptionalReturn(token, abi.encodeCall(token.approve, (spender, 0)));
            _callOptionalReturn(token, approvalCall);
        }
    }

    /**
     * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.
     * Revert on invalid signature.
     */
    function safePermit(
        IERC20Permit token,
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) internal {
        uint256 nonceBefore = token.nonces(owner);
        token.permit(owner, spender, value, deadline, v, r, s);
        uint256 nonceAfter = token.nonces(owner);
        if (nonceAfter != nonceBefore + 1) {
            revert SafeERC20FailedOperation(address(token));
        }
    }

    /**
     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
     * on the return value: the return value is optional (but if data is returned, it must not be false).
     * @param token The token targeted by the call.
     * @param data The call data (encoded using abi.encode or one of its variants).
     */
    function _callOptionalReturn(IERC20 token, bytes memory data) private {
        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
        // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that
        // the target address contains contract code and also asserts for success in the low-level call.

        bytes memory returndata = address(token).functionCall(data);
        if (returndata.length != 0 && !abi.decode(returndata, (bool))) {
            revert SafeERC20FailedOperation(address(token));
        }
    }

    /**
     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
     * on the return value: the return value is optional (but if data is returned, it must not be false).
     * @param token The token targeted by the call.
     * @param data The call data (encoded using abi.encode or one of its variants).
     *
     * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.
     */
    function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {
        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
        // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false
        // and not revert is the subcall reverts.

        (bool success, bytes memory returndata) = address(token).call(data);
        return success && (returndata.length == 0 || abi.decode(returndata, (bool))) && address(token).code.length > 0;
    }
}

File 4 of 6 : IERC20.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)

pragma solidity ^0.8.20;

/**
 * @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 value of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the value of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Moves a `value` amount of 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 value) 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 a `value` amount of tokens 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 value) external returns (bool);

    /**
     * @dev Moves a `value` amount of tokens from `from` to `to` using the
     * allowance mechanism. `value` 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 value) external returns (bool);
}

File 5 of 6 : IERC20Permit.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)

pragma solidity ^0.8.20;

/**
 * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in
 * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].
 *
 * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by
 * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't
 * need to send a transaction, and thus is not required to hold Ether at all.
 */
interface IERC20Permit {
    /**
     * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,
     * given ``owner``'s signed approval.
     *
     * IMPORTANT: The same issues {IERC20-approve} has related to transaction
     * ordering also apply here.
     *
     * Emits an {Approval} event.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     * - `deadline` must be a timestamp in the future.
     * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`
     * over the EIP712-formatted function arguments.
     * - the signature must use ``owner``'s current nonce (see {nonces}).
     *
     * For more information on the signature format, see the
     * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP
     * section].
     */
    function permit(
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external;

    /**
     * @dev Returns the current nonce for `owner`. This value must be
     * included whenever a signature is generated for {permit}.
     *
     * Every successful call to {permit} increases ``owner``'s nonce by one. This
     * prevents a signature from being used multiple times.
     */
    function nonces(address owner) external view returns (uint256);

    /**
     * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.
     */
    // solhint-disable-next-line func-name-mixedcase
    function DOMAIN_SEPARATOR() external view returns (bytes32);
}

File 6 of 6 : Address.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)

pragma solidity ^0.8.20;

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev The ETH balance of the account is not enough to perform the operation.
     */
    error AddressInsufficientBalance(address account);

    /**
     * @dev There's no code at `target` (it is not a contract).
     */
    error AddressEmptyCode(address target);

    /**
     * @dev A call to an address target failed. The target may have reverted.
     */
    error FailedInnerCall();

    /**
     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
     * `recipient`, forwarding all available gas and reverting on errors.
     *
     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
     * of certain opcodes, possibly making contracts go over the 2300 gas limit
     * imposed by `transfer`, making them unable to receive funds via
     * `transfer`. {sendValue} removes this limitation.
     *
     * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].
     *
     * IMPORTANT: because control is transferred to `recipient`, care must be
     * taken to not create reentrancy vulnerabilities. Consider using
     * {ReentrancyGuard} or the
     * https://solidity.readthedocs.io/en/v0.8.20/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
     */
    function sendValue(address payable recipient, uint256 amount) internal {
        if (address(this).balance < amount) {
            revert AddressInsufficientBalance(address(this));
        }

        (bool success, ) = recipient.call{value: amount}("");
        if (!success) {
            revert FailedInnerCall();
        }
    }

    /**
     * @dev Performs a Solidity function call using a low level `call`. A
     * plain `call` is an unsafe replacement for a function call: use this
     * function instead.
     *
     * If `target` reverts with a revert reason or custom error, it is bubbled
     * up by this function (like regular Solidity function calls). However, if
     * the call reverted with no returned reason, this function reverts with a
     * {FailedInnerCall} error.
     *
     * Returns the raw returned data. To convert to the expected return value,
     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
     *
     * Requirements:
     *
     * - `target` must be a contract.
     * - calling `target` with `data` must not revert.
     */
    function functionCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionCallWithValue(target, data, 0);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but also transferring `value` wei to `target`.
     *
     * Requirements:
     *
     * - the calling contract must have an ETH balance of at least `value`.
     * - the called Solidity function must be `payable`.
     */
    function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
        if (address(this).balance < value) {
            revert AddressInsufficientBalance(address(this));
        }
        (bool success, bytes memory returndata) = target.call{value: value}(data);
        return verifyCallResultFromTarget(target, success, returndata);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a static call.
     */
    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
        (bool success, bytes memory returndata) = target.staticcall(data);
        return verifyCallResultFromTarget(target, success, returndata);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a delegate call.
     */
    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
        (bool success, bytes memory returndata) = target.delegatecall(data);
        return verifyCallResultFromTarget(target, success, returndata);
    }

    /**
     * @dev Tool to verify that a low level call to smart-contract was successful, and reverts if the target
     * was not a contract or bubbling up the revert reason (falling back to {FailedInnerCall}) in case of an
     * unsuccessful call.
     */
    function verifyCallResultFromTarget(
        address target,
        bool success,
        bytes memory returndata
    ) internal view returns (bytes memory) {
        if (!success) {
            _revert(returndata);
        } else {
            // only check if target is a contract if the call was successful and the return data is empty
            // otherwise we already know that it was a contract
            if (returndata.length == 0 && target.code.length == 0) {
                revert AddressEmptyCode(target);
            }
            return returndata;
        }
    }

    /**
     * @dev Tool to verify that a low level call was successful, and reverts if it wasn't, either by bubbling the
     * revert reason or with a default {FailedInnerCall} error.
     */
    function verifyCallResult(bool success, bytes memory returndata) internal pure returns (bytes memory) {
        if (!success) {
            _revert(returndata);
        } else {
            return returndata;
        }
    }

    /**
     * @dev Reverts with returndata if present. Otherwise reverts with {FailedInnerCall}.
     */
    function _revert(bytes memory returndata) private pure {
        // Look for revert reason and bubble it up if present
        if (returndata.length > 0) {
            // The easiest way to bubble the revert reason is using memory via assembly
            /// @solidity memory-safe-assembly
            assembly {
                let returndata_size := mload(returndata)
                revert(add(32, returndata), returndata_size)
            }
        } else {
            revert FailedInnerCall();
        }
    }
}

Settings
{
  "remappings": [
    "forge-std/=lib/forge-std/src/",
    "solmate/=lib/solmate/src/",
    "ds-test/=lib/forge-std/lib/ds-test/src/",
    "@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/",
    "@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/",
    "@/=src/",
    "@solady/=lib/solady/src/",
    "@unifapv2/=src/UnifapV2/",
    "clones/=lib/clones-with-immutable-args/src/",
    "@openzeppelin/=lib/openzeppelin-contracts/contracts/",
    "@clones/=lib/unifap-v2/lib/clones-with-immutable-args/src/",
    "@ds/=lib/unifap-v2/lib/ds-test/src/",
    "@solmate/=lib/unifap-v2/lib/solmate/src/",
    "@std/=lib/unifap-v2/lib/forge-std/src/",
    "abdk-libraries-solidity/=lib/abdk-libraries-solidity/",
    "clones-with-immutable-args/=lib/clones-with-immutable-args/src/",
    "clones/=lib/unifap-v2/lib/clones-with-immutable-args/src/",
    "erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/",
    "openzeppelin-contracts/=lib/openzeppelin-contracts/",
    "solady/=lib/solady/",
    "unifap-v2/=lib/unifap-v2/src/"
  ],
  "optimizer": {
    "enabled": true,
    "runs": 1000000
  },
  "metadata": {
    "useLiteralContent": false,
    "bytecodeHash": "ipfs",
    "appendCBOR": true
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "evmVersion": "paris",
  "libraries": {
    "src/libraries/HalfLife.sol": {
      "HalfLife": "0xcf4d7552ca9f07c474d69e89a88943fabb60b199"
    },
    "src/libraries/HalfLifeCarbonCreditAuction.sol": {
      "HalfLifeCarbonCreditAuction": "0xd178525026bafc51d045a2e98b0c79a526d446de"
    }
  }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"_vetoCouncil","type":"address"},{"internalType":"address","name":"_minerPool","type":"address"}],"stateMutability":"payable","type":"constructor"},{"inputs":[{"internalType":"address","name":"target","type":"address"}],"name":"AddressEmptyCode","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"AddressInsufficientBalance","type":"error"},{"inputs":[],"name":"AlreadyWithdrawnFromHolding","type":"error"},{"inputs":[],"name":"CallerMustBeVetoCouncilMember","type":"error"},{"inputs":[],"name":"DelayStillOnCooldown","type":"error"},{"inputs":[],"name":"FailedInnerCall","type":"error"},{"inputs":[],"name":"MinerPoolAlreadySet","type":"error"},{"inputs":[],"name":"NetworkIsFrozen","type":"error"},{"inputs":[],"name":"OnlyMinerPoolCanAddHoldings","type":"error"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"SafeERC20FailedOperation","type":"error"},{"inputs":[],"name":"WithdrawalNotReady","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint192","name":"amount","type":"uint192"}],"name":"HoldingAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint192","name":"amount","type":"uint192"}],"name":"HoldingClaimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"vetoAgent","type":"address"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"NetworkDelay","type":"event"},{"inputs":[],"name":"DEFAULT_DELAY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"FIVE_WEEKS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MINER_POOL","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"NINETY_DAYS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"VETO_COUNCIL","outputs":[{"internalType":"contract IVetoCouncil","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"VETO_HOLDING_DELAY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint192","name":"amount","type":"uint192"}],"name":"addHolding","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"address","name":"token","type":"address"}],"name":"claimHoldingSingleton","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"user","type":"address"},{"internalType":"address","name":"token","type":"address"}],"internalType":"struct ClaimHoldingArgs[]","name":"args","type":"tuple[]"}],"name":"claimHoldings","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"delayNetwork","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"address","name":"token","type":"address"}],"name":"holdings","outputs":[{"components":[{"internalType":"uint192","name":"amount","type":"uint192"},{"internalType":"uint64","name":"expirationTimestamp","type":"uint64"}],"internalType":"struct Holding","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isNetworkFrozen","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minimumWithdrawTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]

60c0604052604051610f9a380380610f9a83398101604081905261002291610055565b6001600160a01b039182166080521660a052610088565b80516001600160a01b038116811461005057600080fd5b919050565b6000806040838503121561006857600080fd5b61007183610039565b915061007f60208401610039565b90509250929050565b60805160a051610edf6100bb60003960008181610219015261030a0152600081816101b201526104f30152610edf6000f3fe608060405234801561001057600080fd5b50600436106100df5760003560e01c80636334295c1161008c57806396c273251161006657806396c27325146101f9578063c6d1382514610201578063d203d5a014610214578063e372c9001461023b57600080fd5b80636334295c14610199578063659495a0146101a35780637a647189146101ad57600080fd5b80634036ff2e116100bd5780634036ff2e1461011f5780634710707e146101715780634cc2cb671461018657600080fd5b80630ba36e2a146100e4578063250415c2146100fe5780632d7202d114610116575b600080fd5b600054421060405190151581526020015b60405180910390f35b6101086277f88081565b6040519081526020016100f5565b61010860005481565b61013261012d366004610b82565b610245565b60408051825177ffffffffffffffffffffffffffffffffffffffffffffffff16815260209283015167ffffffffffffffff1692810192909252016100f5565b61018461017f366004610b82565b6102dd565b005b610184610194366004610bb5565b6102f2565b610108622e248081565b61010862093a8081565b6101d47f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100f5565b6101846104c5565b61018461020f366004610cc0565b610650565b6101d47f000000000000000000000000000000000000000000000000000000000000000081565b6101086276a70081565b6040805180820182526000808252602091820181905273ffffffffffffffffffffffffffffffffffffffff8581168252600183528382209085168252825282902082518084019093525477ffffffffffffffffffffffffffffffffffffffffffffffff811683527801000000000000000000000000000000000000000000000000900467ffffffffffffffff16908201525b92915050565b60005442106102ed8383836106a6565b505050565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610358576103587f4b1c64be00000000000000000000000000000000000000000000000000000000610808565b73ffffffffffffffffffffffffffffffffffffffff8084166000908152600160209081526040808320938616835292905290812080548392906103b690849077ffffffffffffffffffffffffffffffffffffffffffffffff16610dcb565b92506101000a81548177ffffffffffffffffffffffffffffffffffffffffffffffff021916908377ffffffffffffffffffffffffffffffffffffffffffffffff16021790555062093a804261040b9190610e03565b73ffffffffffffffffffffffffffffffffffffffff848116600081815260016020908152604080832094881680845294825291829020805467ffffffffffffffff9690961678010000000000000000000000000000000000000000000000000277ffffffffffffffffffffffffffffffffffffffffffffffff96871617905590519385168452919290917fae545d17d6faf72c4c01b498f7cce7af390ab49fccfba315036e414af2a29e10910160405180910390a3505050565b6040517febd7dc520000000000000000000000000000000000000000000000000000000081523360048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063ebd7dc5290602401602060405180830381865afa15801561054f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105739190610e16565b6105a0576105a07f7ec0374500000000000000000000000000000000000000000000000000000000610808565b60008054908190036105f7576105b96277f88042610e03565b600055604080513381524260208201527f337b6c2d86ade4ff07f8f386b280cdd2414d551ade60595e13d20d349b633de9910160405180910390a150565b8042101561064357600061060b4283610e38565b9050622e2480811115610641576106417f3f7cf00a00000000000000000000000000000000000000000000000000000000610808565b505b6105b96277f88042610e03565b600080544210825190915060005b818110156106a057600084828151811061067a5761067a610e4b565b6020026020010151905061069781600001518260200151866106a6565b5060010161065e565b50505050565b73ffffffffffffffffffffffffffffffffffffffff838116600090815260016020908152604080832093861683529281529082902082518084019093525477ffffffffffffffffffffffffffffffffffffffffffffffff811683527801000000000000000000000000000000000000000000000000900467ffffffffffffffff169082018190526107379083610812565b73ffffffffffffffffffffffffffffffffffffffff80851660009081526001602090815260408083209387168352929052908120558051610795908490869077ffffffffffffffffffffffffffffffffffffffffffffffff1661089e565b805160405177ffffffffffffffffffffffffffffffffffffffffffffffff909116815273ffffffffffffffffffffffffffffffffffffffff80851691908616907fc061323b879f183a20cdba85c0bf51c12ac3149240980e63f4590c28a350a9279060200160405180910390a350505050565b8060005260046000fd5b8167ffffffffffffffff1642101561084d5761084d7f0f2ca6e700000000000000000000000000000000000000000000000000000000610808565b6276a70061086567ffffffffffffffff841642610e38565b101561089a57801561089a5761089a7f3bc996a900000000000000000000000000000000000000000000000000000000610808565b5050565b6040805173ffffffffffffffffffffffffffffffffffffffff848116602483015260448083018590528351808403909101815260649092019092526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb000000000000000000000000000000000000000000000000000000001790526102ed91859190600090610937908416836109b0565b9050805160001415801561095c57508080602001905181019061095a9190610e16565b155b156102ed576040517f5274afe700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff841660048201526024015b60405180910390fd5b60606109be838360006109c5565b9392505050565b606081471015610a03576040517fcd7860590000000000000000000000000000000000000000000000000000000081523060048201526024016109a7565b6000808573ffffffffffffffffffffffffffffffffffffffff168486604051610a2c9190610e7a565b60006040518083038185875af1925050503d8060008114610a69576040519150601f19603f3d011682016040523d82523d6000602084013e610a6e565b606091505b5091509150610a7e868383610a88565b9695505050505050565b606082610a9d57610a9882610b17565b6109be565b8151158015610ac1575073ffffffffffffffffffffffffffffffffffffffff84163b155b15610b10576040517f9996b31500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff851660048201526024016109a7565b50806109be565b805115610b275780518082602001fd5b6040517f1425ea4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b803573ffffffffffffffffffffffffffffffffffffffff81168114610b7d57600080fd5b919050565b60008060408385031215610b9557600080fd5b610b9e83610b59565b9150610bac60208401610b59565b90509250929050565b600080600060608486031215610bca57600080fd5b610bd384610b59565b9250610be160208501610b59565b9150604084013577ffffffffffffffffffffffffffffffffffffffffffffffff81168114610c0e57600080fd5b809150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715610c6b57610c6b610c19565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715610cb857610cb8610c19565b604052919050565b60006020808385031215610cd357600080fd5b823567ffffffffffffffff80821115610ceb57600080fd5b818501915085601f830112610cff57600080fd5b813581811115610d1157610d11610c19565b610d1f848260051b01610c71565b818152848101925060069190911b830184019087821115610d3f57600080fd5b928401925b81841015610d915760408489031215610d5d5760008081fd5b610d65610c48565b610d6e85610b59565b8152610d7b868601610b59565b8187015283526040939093019291840191610d44565b979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b77ffffffffffffffffffffffffffffffffffffffffffffffff818116838216019080821115610dfc57610dfc610d9c565b5092915050565b808201808211156102d7576102d7610d9c565b600060208284031215610e2857600080fd5b815180151581146109be57600080fd5b818103818111156102d7576102d7610d9c565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000825160005b81811015610e9b5760208186018101518583015201610e81565b50600092019182525091905056fea2646970667358221220e0b304c33d897a38ece7beee47647d0a0b75355876abc0e4779c86f43c9b415b64736f6c63430008150033000000000000000000000000a3a32d3c9a5a593bc35d69bacbe2df5ea2c3cf5c0000000000000000000000006fa8c7a89b22bf3212392b778905b12f3dbaf5c4

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106100df5760003560e01c80636334295c1161008c57806396c273251161006657806396c27325146101f9578063c6d1382514610201578063d203d5a014610214578063e372c9001461023b57600080fd5b80636334295c14610199578063659495a0146101a35780637a647189146101ad57600080fd5b80634036ff2e116100bd5780634036ff2e1461011f5780634710707e146101715780634cc2cb671461018657600080fd5b80630ba36e2a146100e4578063250415c2146100fe5780632d7202d114610116575b600080fd5b600054421060405190151581526020015b60405180910390f35b6101086277f88081565b6040519081526020016100f5565b61010860005481565b61013261012d366004610b82565b610245565b60408051825177ffffffffffffffffffffffffffffffffffffffffffffffff16815260209283015167ffffffffffffffff1692810192909252016100f5565b61018461017f366004610b82565b6102dd565b005b610184610194366004610bb5565b6102f2565b610108622e248081565b61010862093a8081565b6101d47f000000000000000000000000a3a32d3c9a5a593bc35d69bacbe2df5ea2c3cf5c81565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100f5565b6101846104c5565b61018461020f366004610cc0565b610650565b6101d47f0000000000000000000000006fa8c7a89b22bf3212392b778905b12f3dbaf5c481565b6101086276a70081565b6040805180820182526000808252602091820181905273ffffffffffffffffffffffffffffffffffffffff8581168252600183528382209085168252825282902082518084019093525477ffffffffffffffffffffffffffffffffffffffffffffffff811683527801000000000000000000000000000000000000000000000000900467ffffffffffffffff16908201525b92915050565b60005442106102ed8383836106a6565b505050565b3373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000006fa8c7a89b22bf3212392b778905b12f3dbaf5c41614610358576103587f4b1c64be00000000000000000000000000000000000000000000000000000000610808565b73ffffffffffffffffffffffffffffffffffffffff8084166000908152600160209081526040808320938616835292905290812080548392906103b690849077ffffffffffffffffffffffffffffffffffffffffffffffff16610dcb565b92506101000a81548177ffffffffffffffffffffffffffffffffffffffffffffffff021916908377ffffffffffffffffffffffffffffffffffffffffffffffff16021790555062093a804261040b9190610e03565b73ffffffffffffffffffffffffffffffffffffffff848116600081815260016020908152604080832094881680845294825291829020805467ffffffffffffffff9690961678010000000000000000000000000000000000000000000000000277ffffffffffffffffffffffffffffffffffffffffffffffff96871617905590519385168452919290917fae545d17d6faf72c4c01b498f7cce7af390ab49fccfba315036e414af2a29e10910160405180910390a3505050565b6040517febd7dc520000000000000000000000000000000000000000000000000000000081523360048201527f000000000000000000000000a3a32d3c9a5a593bc35d69bacbe2df5ea2c3cf5c73ffffffffffffffffffffffffffffffffffffffff169063ebd7dc5290602401602060405180830381865afa15801561054f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105739190610e16565b6105a0576105a07f7ec0374500000000000000000000000000000000000000000000000000000000610808565b60008054908190036105f7576105b96277f88042610e03565b600055604080513381524260208201527f337b6c2d86ade4ff07f8f386b280cdd2414d551ade60595e13d20d349b633de9910160405180910390a150565b8042101561064357600061060b4283610e38565b9050622e2480811115610641576106417f3f7cf00a00000000000000000000000000000000000000000000000000000000610808565b505b6105b96277f88042610e03565b600080544210825190915060005b818110156106a057600084828151811061067a5761067a610e4b565b6020026020010151905061069781600001518260200151866106a6565b5060010161065e565b50505050565b73ffffffffffffffffffffffffffffffffffffffff838116600090815260016020908152604080832093861683529281529082902082518084019093525477ffffffffffffffffffffffffffffffffffffffffffffffff811683527801000000000000000000000000000000000000000000000000900467ffffffffffffffff169082018190526107379083610812565b73ffffffffffffffffffffffffffffffffffffffff80851660009081526001602090815260408083209387168352929052908120558051610795908490869077ffffffffffffffffffffffffffffffffffffffffffffffff1661089e565b805160405177ffffffffffffffffffffffffffffffffffffffffffffffff909116815273ffffffffffffffffffffffffffffffffffffffff80851691908616907fc061323b879f183a20cdba85c0bf51c12ac3149240980e63f4590c28a350a9279060200160405180910390a350505050565b8060005260046000fd5b8167ffffffffffffffff1642101561084d5761084d7f0f2ca6e700000000000000000000000000000000000000000000000000000000610808565b6276a70061086567ffffffffffffffff841642610e38565b101561089a57801561089a5761089a7f3bc996a900000000000000000000000000000000000000000000000000000000610808565b5050565b6040805173ffffffffffffffffffffffffffffffffffffffff848116602483015260448083018590528351808403909101815260649092019092526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb000000000000000000000000000000000000000000000000000000001790526102ed91859190600090610937908416836109b0565b9050805160001415801561095c57508080602001905181019061095a9190610e16565b155b156102ed576040517f5274afe700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff841660048201526024015b60405180910390fd5b60606109be838360006109c5565b9392505050565b606081471015610a03576040517fcd7860590000000000000000000000000000000000000000000000000000000081523060048201526024016109a7565b6000808573ffffffffffffffffffffffffffffffffffffffff168486604051610a2c9190610e7a565b60006040518083038185875af1925050503d8060008114610a69576040519150601f19603f3d011682016040523d82523d6000602084013e610a6e565b606091505b5091509150610a7e868383610a88565b9695505050505050565b606082610a9d57610a9882610b17565b6109be565b8151158015610ac1575073ffffffffffffffffffffffffffffffffffffffff84163b155b15610b10576040517f9996b31500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff851660048201526024016109a7565b50806109be565b805115610b275780518082602001fd5b6040517f1425ea4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b803573ffffffffffffffffffffffffffffffffffffffff81168114610b7d57600080fd5b919050565b60008060408385031215610b9557600080fd5b610b9e83610b59565b9150610bac60208401610b59565b90509250929050565b600080600060608486031215610bca57600080fd5b610bd384610b59565b9250610be160208501610b59565b9150604084013577ffffffffffffffffffffffffffffffffffffffffffffffff81168114610c0e57600080fd5b809150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715610c6b57610c6b610c19565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715610cb857610cb8610c19565b604052919050565b60006020808385031215610cd357600080fd5b823567ffffffffffffffff80821115610ceb57600080fd5b818501915085601f830112610cff57600080fd5b813581811115610d1157610d11610c19565b610d1f848260051b01610c71565b818152848101925060069190911b830184019087821115610d3f57600080fd5b928401925b81841015610d915760408489031215610d5d5760008081fd5b610d65610c48565b610d6e85610b59565b8152610d7b868601610b59565b8187015283526040939093019291840191610d44565b979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b77ffffffffffffffffffffffffffffffffffffffffffffffff818116838216019080821115610dfc57610dfc610d9c565b5092915050565b808201808211156102d7576102d7610d9c565b600060208284031215610e2857600080fd5b815180151581146109be57600080fd5b818103818111156102d7576102d7610d9c565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000825160005b81811015610e9b5760208186018101518583015201610e81565b50600092019182525091905056fea2646970667358221220e0b304c33d897a38ece7beee47647d0a0b75355876abc0e4779c86f43c9b415b64736f6c63430008150033

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

000000000000000000000000a3a32d3c9a5a593bc35d69bacbe2df5ea2c3cf5c0000000000000000000000006fa8c7a89b22bf3212392b778905b12f3dbaf5c4

-----Decoded View---------------
Arg [0] : _vetoCouncil (address): 0xA3A32d3c9a5A593bc35D69BACbe2dF5Ea2C3cF5C
Arg [1] : _minerPool (address): 0x6Fa8C7a89b22bf3212392b778905B12f3dBAF5C4

-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 000000000000000000000000a3a32d3c9a5a593bc35d69bacbe2df5ea2c3cf5c
Arg [1] : 0000000000000000000000006fa8c7a89b22bf3212392b778905b12f3dbaf5c4


Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

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

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.