Cryo Explorer Ethereum Mainnet

Address Contract Verified

Address 0x43F8F8472FEbd6e7481e0AB43F49A683F9Fbedb7
Balance 0 ETH
Nonce 1
Code Size 3379 bytes
Indexed Transactions 0
External Etherscan · Sourcify

Contract Bytecode

3379 bytes
0x608060405234801561001057600080fd5b50600436106100f55760003560e01c8063238efcbc11610097578063d38bfff411610066578063d38bfff41461021b578063d63a8e111461022e578063ee114e4d14610261578063f41a1dfc1461028857600080fd5b8063238efcbc146101da5780635aa6e675146101e25780638070c503146101f5578063b7c58d7a1461020857600080fd5b8063170c95b7116100d3578063170c95b71461016657806317f29e931461018d5780631b552a25146101b45780631f316bdc146101c757600080fd5b806308af4d88146100fa5780630b0a88e91461010f5780630b50542814610153575b600080fd5b61010d61010836600461096b565b6102ab565b005b6101367f000000000000000000000000a7641acbc1e85a7ed70ea7bcffb91afb12ad0c5481565b6040516001600160a01b0390911681526020015b60405180910390f35b61010d6101613660046109d9565b610322565b6101367f00000000000000000000000044087e105137a5095c008aab6a6530182821f2f081565b6101367f000000000000000000000000b0552b6860ce5c0202976db056b5e3cc4f9cc76581565b61010d6101c2366004610a45565b61059a565b61010d6101d5366004610ad7565b61075f565b61010d6107cf565b600054610136906001600160a01b031681565b600154610136906001600160a01b031681565b61010d61021636600461096b565b610838565b61010d61022936600461096b565b6108ac565b61025161023c36600461096b565b60026020526000908152604090205460ff1681565b604051901515815260200161014a565b6101367f000000000000000000000000d8fa8dc5adec503acc5e026a98f32ca5c1fa289a81565b61025161029636600461096b565b60036020526000908152604090205460ff1681565b6000546001600160a01b031633146102d6576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b038116600081815260026020526040808220805460ff19166001179055517f5d20d7597e8195aa92d4ad63482761cfbbe7c4afdef190f27182702924c9af779190a250565b6000546001600160a01b031633148061034a57503360009081526002602052604090205460ff165b6103675760405163ea8e4eb560e01b815260040160405180910390fd5b828114610387576040516334d7c90960e11b815260040160405180910390fd5b6000848484846040516024016103a09493929190610b55565b60408051601f198184030181529181526020820180516001600160e01b03166334c3b37760e11b17905251909150600090610403907f00000000000000000000000044087e105137a5095c008aab6a6530182821f2f09083908590602401610c08565b60408051601f198184030181529181526020820180516001600160e01b0316635b0e93fb60e11b17905251909150600090610466907f000000000000000000000000d8fa8dc5adec503acc5e026a98f32ca5c1fa289a9083908590602401610c08565b60408051601f198184030181529181526020820180516001600160e01b0316635b0e93fb60e11b1790525163468721a760e01b81529091506001600160a01b037f000000000000000000000000b0552b6860ce5c0202976db056b5e3cc4f9cc765169063468721a790610504907f000000000000000000000000a7641acbc1e85a7ed70ea7bcffb91afb12ad0c549060009086908290600401610c3e565b6020604051808303816000875af1158015610523573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105479190610c94565b6105915760405162461bcd60e51b8152602060048201526016602482015275436f756c64206e6f74206578656375746520766f746560501b60448201526064015b60405180910390fd5b50505050505050565b6000546001600160a01b03163314806105c257503360009081526002602052604090205460ff165b6105df5760405163ea8e4eb560e01b815260040160405180910390fd5b6001600160a01b03851660009081526003602052604090205460ff1661061857604051631bbf200960e31b815260040160405180910390fd5b828114610638576040516334d7c90960e11b815260040160405180910390fd5b6000848484846040516024016106519493929190610cb1565b60408051601f198184030181529181526020820180516001600160e01b0316634f8dac1760e11b1790525163468721a760e01b81529091506001600160a01b037f000000000000000000000000b0552b6860ce5c0202976db056b5e3cc4f9cc765169063468721a7906106cf90899060009086908290600401610c3e565b6020604051808303816000875af11580156106ee573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107129190610c94565b6107575760405162461bcd60e51b8152602060048201526016602482015275436f756c64206e6f74206578656375746520766f746560501b6044820152606401610588565b505050505050565b6000546001600160a01b031633148061078757503360009081526002602052604090205460ff165b6107a45760405163ea8e4eb560e01b815260040160405180910390fd5b6001600160a01b03919091166000908152600360205260409020805460ff1916911515919091179055565b6001546001600160a01b031633146107fa576040516354348f0360e01b815260040160405180910390fd5b600080546001600160a01b03191633908117825560405190917fa6a85f15b976d399f39ad43e515e75910bac714bc55eeff6131fb90780d6f74691a2565b6000546001600160a01b03163314610863576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b038116600081815260026020526040808220805460ff19169055517f5f1b0fa787087c297cc2ee3a7641860058ab750c330ac3ea5d6d5b9b777f353d9190a250565b6000546001600160a01b031633146108d7576040516354348f0360e01b815260040160405180910390fd5b6001600160a01b03811661092d5760405162461bcd60e51b815260206004820181905260248201527f476f7665726e616e636520616464726573732063616e6e6f74206265203078306044820152606401610588565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b80356001600160a01b038116811461096657600080fd5b919050565b60006020828403121561097d57600080fd5b6109868261094f565b9392505050565b60008083601f84011261099f57600080fd5b50813567ffffffffffffffff8111156109b757600080fd5b6020830191508360208260051b85010111156109d257600080fd5b9250929050565b600080600080604085870312156109ef57600080fd5b843567ffffffffffffffff80821115610a0757600080fd5b610a138883890161098d565b90965094506020870135915080821115610a2c57600080fd5b50610a398782880161098d565b95989497509550505050565b600080600080600060608688031215610a5d57600080fd5b610a668661094f565b9450602086013567ffffffffffffffff80821115610a8357600080fd5b610a8f89838a0161098d565b90965094506040880135915080821115610aa857600080fd5b50610ab58882890161098d565b969995985093965092949392505050565b8015158114610ad457600080fd5b50565b60008060408385031215610aea57600080fd5b610af38361094f565b91506020830135610b0381610ac6565b809150509250929050565b8183526000602080850194508260005b85811015610b4a576001600160a01b03610b378361094f565b1687529582019590820190600101610b1e565b509495945050505050565b604081526000610b69604083018688610b0e565b828103602084810191909152848252859181016000805b87811015610bb357843567ffffffffffffffff8116808214610ba0578384fd5b8452509383019391830191600101610b80565b50909998505050505050505050565b6000815180845260005b81811015610be857602081850181015186830182015201610bcc565b506000602082860101526020601f19601f83011685010191505092915050565b6001600160a01b038416815260ff83166020820152606060408201819052600090610c3590830184610bc2565b95945050505050565b60018060a01b0385168152836020820152608060408201526000610c656080830185610bc2565b905060028310610c8557634e487b7160e01b600052602160045260246000fd5b82606083015295945050505050565b600060208284031215610ca657600080fd5b815161098681610ac6565b604081526000610cc5604083018688610b0e565b82810360208401528381526001600160fb1b03841115610ce457600080fd5b8360051b8086602084013701602001969550505050505056fea2646970667358221220d93014ecd04d9b4ba84f1daa91064d81080f56c634c41a81af451199724fd92664736f6c63430008130033

Verified Source Code Full Match

Compiler: v0.8.19+commit.7dd6d404 EVM: paris Optimization: Yes (200 runs)
IERC20.sol 78 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.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);
}
GaugeVoter.sol 73 lines
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity ^0.8.19;

import "openzeppelin-contracts/token/ERC20/IERC20.sol";
import "./governance/AllowanceManager.sol";
import "./interfaces/ISafe.sol";
import "./interfaces/ISafeOperation.sol";

contract GaugeVoter is AllowanceManager {

    /// @notice Stake DAO governance owner
    address public immutable SD_SAFE = address(0xB0552b6860CE5C0202976Db056b5e3Cc4f9CC765);
    
    // Pendle data
    address public immutable PENDLE_LOCKER = address(0xD8fa8dC5aDeC503AcC5e026a98F32Ca5C1Fa289A);
    address public immutable PENDLE_VOTER = address(0x44087E105137a5095c008AaB6a6530182821F2F0);
    address public immutable PENDLE_STRATEGY = address(0xA7641acBc1E85A7eD70ea7bCFFB91afb12AD0c54);

    /// @notice Voter contracts allowed
    mapping(address => bool) public VOTERS_ALLOWED;

    constructor() AllowanceManager(msg.sender) {

    }

    /// @notice Bundle gauge votes, _gauges and _weights must have the same length
    /// @param _voter A voter address allowed with toggle_voter(_voter, true)
    /// @param _gauges Array of gauge addresses
    /// @param _weights Array of weights
    function vote_with_voter(address _voter, address[] calldata _gauges, uint256[] calldata _weights) external onlyGovernanceOrAllowed {
        if(!VOTERS_ALLOWED[_voter]) {
            revert VOTER_NOT_ALLOW();
        }

        if(_gauges.length != _weights.length) {
            revert WRONG_DATA();
        }

        bytes memory data = abi.encodeWithSignature("voteGauges(address[],uint256[])", _gauges, _weights);
        require(ISafe(SD_SAFE).execTransactionFromModule(_voter, 0, data, ISafeOperation.Call), "Could not execute vote");
    }

    /// @notice Bundle gauge votes with our strategy contract, _gauges and _weights must have the same length
    /// @param _gauges Array of gauge addresses
    /// @param _weights Array of weights
    function vote_pendle(address[] calldata _gauges, uint64[] calldata _weights) external onlyGovernanceOrAllowed {
        if(_gauges.length != _weights.length) {
            revert WRONG_DATA();
        }

        bytes memory votes_data = abi.encodeWithSignature("vote(address[],uint64[])", _gauges, _weights);
        bytes memory voter_data = abi.encodeWithSignature("execute(address,uint256,bytes)", PENDLE_VOTER, 0, votes_data);
        bytes memory locker_data = abi.encodeWithSignature("execute(address,uint256,bytes)", PENDLE_LOCKER, 0, voter_data);
        require(ISafe(SD_SAFE).execTransactionFromModule(PENDLE_STRATEGY, 0, locker_data, ISafeOperation.Call), "Could not execute vote");
    }

    /// @notice Allow or disallow a voter
    /// @param _voter Voter address
    /// @param _allow True to allow the voter to exec a gauge vote, False to disallow it
    function toggle_voter(address _voter, bool _allow) external onlyGovernanceOrAllowed {
        VOTERS_ALLOWED[_voter] = _allow;
    }

    ////////////////////////////////////////////////////////////////
    /// --- EVENTS & ERRORS
    ///////////////////////////////////////////////////////////////

    /// @notice Error emitted when we try to vote with a voter which is not allowed
    error VOTER_NOT_ALLOW();

    /// @notice Error emitted when we try to vote with gauges length different than weights length
    error WRONG_DATA();
}
AllowanceManager.sol 50 lines
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity ^0.8.19;

import "./Governance.sol";

/// @title AllowanceManager contract.
abstract contract AllowanceManager is Governance {
    /// @notice Mapping of allowed addresses.
    mapping(address => bool) public allowed;

    ////////////////////////////////////////////////////////////////
    /// --- EVENTS & ERRORS
    ///////////////////////////////////////////////////////////////

    /// @notice Event emitted when an address is allowed.
    /// @param allowedAddress Address that was allowed.
    event AddressAllowed(address indexed allowedAddress);

    /// @notice Event emitted when an address is disallowed.
    /// @param disallowedAddress Address that was disallowed.
    event AddressDisallowed(address indexed disallowedAddress);

    /// @notice Error emitted when auth failed
    error NotAuthorized();

    constructor(address _governance) Governance(_governance) {}

    ////////////////////////////////////////////////////////////////
    /// --- MODIFIERS
    ///////////////////////////////////////////////////////////////

    modifier onlyGovernanceOrAllowed() {
        if (!(msg.sender == governance || allowed[msg.sender])) revert NotAuthorized();
        _;
    }

    ////////////////////////////////////////////////////////////
    /// --- FUNCTIONS
    ////////////////////////////////////////////////////////////

    function allowAddress(address _address) external onlyGovernance {
        allowed[_address] = true;
        emit AddressAllowed(_address);
    }

    function disallowAddress(address _address) external onlyGovernance {
        allowed[_address] = false;
        emit AddressDisallowed(_address);
    }
}
Governance.sol 54 lines
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity ^0.8.19;

abstract contract Governance {
    address public governance;
    address public futureGovernance;

    ////////////////////////////////////////////////////////////////
    /// --- EVENTS & ERRORS
    ///////////////////////////////////////////////////////////////

    /// @notice Event emitted when governance is changed.
    /// @param newGovernance Address of the new governance.
    event GovernanceChanged(address indexed newGovernance);

    /// @notice Error emitted when auth failed
    error OnlyGovernance();

    ////////////////////////////////////////////////////////////////
    /// --- MODIFIERS
    ///////////////////////////////////////////////////////////////

    modifier onlyGovernance() {
        if (msg.sender != governance) revert OnlyGovernance();
        _;
    }

    ////////////////////////////////////////////////////////////
    /// --- CONSTRUCTOR
    ////////////////////////////////////////////////////////////

    constructor(address _governance) {
        governance = _governance;
    }

    ////////////////////////////////////////////////////////////
    /// --- FUNCTIONS
    ////////////////////////////////////////////////////////////

    /// @notice Transfer the governance to a new address.
    /// @param _governance Address of the new governance.
    function transferGovernance(address _governance) public onlyGovernance {
        require(_governance != address(0), "Governance address cannot be 0x0");
        futureGovernance = _governance;
    }

    /// @notice Accept the governance transfer.
    function acceptGovernance() public {
        if (msg.sender != futureGovernance) revert OnlyGovernance();

        governance = msg.sender;
        emit GovernanceChanged(msg.sender);
    }
}
ISafe.sol 13 lines
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity ^0.8.19;

import "./ISafeOperation.sol";

interface ISafe {
    /// @dev Allows a Module to execute a Safe transaction without any further confirmations.
    /// @param to Destination address of module transaction.
    /// @param value Ether value of module transaction.
    /// @param data Data payload of module transaction.
    /// @param operation Operation type of module transaction.
    function execTransactionFromModule(address to, uint256 value, bytes calldata data, ISafeOperation operation) external returns (bool success);
}
ISafeOperation.sol 7 lines
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity ^0.8.19;

enum ISafeOperation {
    Call,
    DelegateCall
}

Read Contract

PENDLE_LOCKER 0xee114e4d → address
PENDLE_STRATEGY 0x0b0a88e9 → address
PENDLE_VOTER 0x170c95b7 → address
SD_SAFE 0x17f29e93 → address
VOTERS_ALLOWED 0xf41a1dfc → bool
allowed 0xd63a8e11 → bool
futureGovernance 0x8070c503 → address
governance 0x5aa6e675 → address

Write Contract 7 functions

These functions modify contract state and require a wallet transaction to execute.

acceptGovernance 0x238efcbc
No parameters
allowAddress 0x08af4d88
address _address
disallowAddress 0xb7c58d7a
address _address
toggle_voter 0x1f316bdc
address _voter
bool _allow
transferGovernance 0xd38bfff4
address _governance
vote_pendle 0x0b505428
address[] _gauges
uint64[] _weights
vote_with_voter 0x1b552a25
address _voter
address[] _gauges
uint256[] _weights

Recent Transactions

No transactions found for this address