账户
0x80...c146
xAAVEa

xAAVEa

$500
此合同的源代码已经过验证!
合同元数据
编译器
0.6.2+commit.bacdbe57
语言
Solidity
合同源代码
文件 1 的 1:xAAVEProxy.sol
// File: contracts/proxies/xAAVEProxy.sol

pragma solidity 0.6.2;

/**
 * @title Proxy - Generic proxy contract allows to execute all transactions
 */

contract xAAVEProxy {

    // storage position of the address of the current implementation
    bytes32 private constant IMPLEMENTATION_POSITION = keccak256("xaave.implementationPosition");
    bytes32 private constant PROPOSED_IMPLEMENTATION_POSITION = keccak256("xaave.proposedImplementationPosition");

    bytes32 private constant PROXY_ADMIN_POSITION = keccak256("xaave.proxyAdmin");
    bytes32 private constant PROXY_COSIGNER1_POSITION = keccak256("xaave.cosigner1");
    bytes32 private constant PROXY_COSIGNER2_POSITION = keccak256("xaave.cosigner2");

    bytes32 private constant PROPOSED_NEW_ADMIN  = keccak256("xaave.proposedNewAdmin");
    bytes32 private constant PROPOSED_NEW_ADMIN_TIMESTAMP  = keccak256("xaave.proposedNewAdminTimestamp");

    modifier onlyProxyAdmin() {
        require(msg.sender == readAddressAtPosition(PROXY_ADMIN_POSITION));
        _;
    }

    modifier onlySigner() {
        address signer1 = readAddressAtPosition(PROXY_COSIGNER1_POSITION);
        address signer2 = readAddressAtPosition(PROXY_COSIGNER2_POSITION);
        require(msg.sender == signer1 || msg.sender == signer2);
        _;
    }

    /**
     * @dev Constructor function sets address of master copy contract.
     * @param implementation the address of the implementation contract that this proxy uses
     * @param proxyAdmin the address of the admin of this proxy
     * @param signer1 the first signer of this proxy
     * @param signer2 the second signer of this proxy
     */
    constructor(
        address implementation,
        address proxyAdmin,
        address signer1,
        address signer2
    ) public {
        require(
            implementation != address(0),
            "Invalid implementation address provided"
        );
        require(
            proxyAdmin != address(0),
            "Invalid proxyAdmin address provided"
        );
        require(signer1 != address(0), "Invalid signer1 address provided");
        require(signer2 != address(0), "Invalid signer2 address provided");
        require(signer1 != signer2, "Signers must have different addresses");
        setNewAddressAtPosition(IMPLEMENTATION_POSITION, implementation);
        setNewAddressAtPosition(PROXY_ADMIN_POSITION, proxyAdmin);
        setNewAddressAtPosition(PROXY_COSIGNER1_POSITION, signer1);
        setNewAddressAtPosition(PROXY_COSIGNER2_POSITION, signer2);
    }

    /**
     * @dev Proposes a new implementation contract for this proxy if sender is the Admin
     * @param newImplementation the address of the new implementation
     */
    function proposeNewImplementation(address newImplementation) public onlyProxyAdmin {
        require(newImplementation != address(0), "new proposed implementation cannot be address(0)");
        require(isContract(newImplementation), "new proposed implementation is not a contract");
        require(newImplementation != implementation(), "new proposed address cannot be the same as the current implementation address");
        setNewAddressAtPosition(PROPOSED_IMPLEMENTATION_POSITION, newImplementation);
    }

    /**
     * @dev Confirms a previously proposed implementation if the sender is one of the two cosigners
     * @param confirmedImplementation the address of previously proposed implementation (has to match the previously proposed implementation)
     */
    function confirmImplementation(address confirmedImplementation)
        public
        onlySigner
    {
        address proposedImplementation = readAddressAtPosition(
            PROPOSED_IMPLEMENTATION_POSITION
        );
        require(
            proposedImplementation != address(0),
            "proposed implementation cannot be address(0)"
        );
        require(
            confirmedImplementation == proposedImplementation,
            "proposed implementation doesn't match the confirmed implementation"
        );
        setNewAddressAtPosition(IMPLEMENTATION_POSITION, confirmedImplementation);
        setNewAddressAtPosition(PROPOSED_IMPLEMENTATION_POSITION, address(0));
    }

    /**
     * @dev Proposes a new admin address if the sender is the Admin
     * @param newAdminAddress address of the new admin role
     */
    function proposeAdminTransfer(address newAdminAddress) public onlyProxyAdmin {
        require(newAdminAddress != address(0), "new Admin address cannot be address(0)");
        setProposedAdmin(newAdminAddress);
    }


    /**
     * @dev Changes the admin address to the previously proposed admin address if 24 hours has past since it was proposed
     */
    function confirmAdminTransfer() public onlyProxyAdmin {
        address newAdminAddress = proposedNewAdmin();
        require(newAdminAddress != address(0), "new Admin address cannot be address(0)");
        require(proposedNewAdminTimestamp() + 1 days <= block.timestamp, "admin change can only be submitted after 1 day");
        setProxyAdmin(newAdminAddress);
        setProposedAdmin(address(0));
    }

    /**
     * @dev Returns whether address is a contract
     */
    function isContract(address _addr) private view returns (bool){
        uint32 size;
        assembly {
            size := extcodesize(_addr)
        }
        return (size > 0);
    }

    /**
     * @dev Returns the address of the implementation contract of this proxy
     */
    function implementation() public view returns (address impl) {
        impl = readAddressAtPosition(IMPLEMENTATION_POSITION);
    }

    /**
     * @dev Returns the admin address of this proxy
     */
    function proxyAdmin() public view returns (address admin) {
        admin = readAddressAtPosition(PROXY_ADMIN_POSITION);
    }

    /**
     * @dev Returns the new proposed implementation address of this proxy (if there is no proposed implementations, returns address(0x0))
     */
    function proposedNewImplementation() public view returns (address impl) {
        impl = readAddressAtPosition(PROPOSED_IMPLEMENTATION_POSITION);
    }

    /**
     * @dev Returns the new proposed admin address of this proxy (if there is no proposed implementations, returns address(0x0))
     */
    function proposedNewAdmin() public view returns (address newAdmin) {
        newAdmin = readAddressAtPosition(PROPOSED_NEW_ADMIN);
    }

    /**
     * @dev Returns the timestamp that the proposed admin can be changed/confirmed
     */
    function proposedNewAdminTimestamp() public view returns (uint256 timestamp) {
        timestamp = readIntAtPosition(PROPOSED_NEW_ADMIN_TIMESTAMP);
    }

    /**
     * @dev Returns the address of the first cosigner if 'id' == 0, otherwise returns the address of the second cosigner
     */
    function proxySigner(uint256 id) public view returns (address signer) {
        if (id == 0) {
            signer = readAddressAtPosition(PROXY_COSIGNER1_POSITION);
        } else {
            signer = readAddressAtPosition(PROXY_COSIGNER2_POSITION);
        }
    }

    /**
     * @dev Returns the proxy type, specified by EIP-897
     * @return Always return 2
     **/
    function proxyType() public pure returns (uint256) {
        return 2; // type 2 is for upgradeable proxy as per EIP-897
    }


    function setProposedAdmin(address proposedAdmin) private {
        setNewAddressAtPosition(PROPOSED_NEW_ADMIN, proposedAdmin);
        setNewIntAtPosition(PROPOSED_NEW_ADMIN_TIMESTAMP, block.timestamp + 1 days);
    }

    function setProxyAdmin(address newAdmin) private {
        setNewAddressAtPosition(PROXY_ADMIN_POSITION, newAdmin);
    }

    function setNewAddressAtPosition(bytes32 position, address newAddr) private {
        assembly { sstore(position, newAddr) }
    }

    function readAddressAtPosition(bytes32 position) private view returns (address result) {
        assembly { result := sload(position) }
    }

    function setNewIntAtPosition(bytes32 position, uint256 newInt) private {
        assembly { sstore(position, newInt) }
    }

    function readIntAtPosition(bytes32 position) private view returns (uint256 result) {
        assembly { result := sload(position) }
    }

    /**
     * @dev Fallback function forwards all transactions and returns all received return data.
     */
    fallback() external payable {
        address impl = implementation();
        // solium-disable-next-line security/no-inline-assembly
        assembly {
            // Copy msg.data. We take full control of memory in this inline assembly
            // block because it will not return to Solidity code. We overwrite the
            // Solidity scratch pad at memory position 0.
            calldatacopy(0, 0, calldatasize())

            // Call the implementation.
            // out and outsize are 0 because we don't know the size yet.
            let result := delegatecall(gas(), impl, 0, calldatasize(), 0, 0)

            // Copy the returned data.
            returndatacopy(0, 0, returndatasize())

            switch result
            // delegatecall returns 0 on error.
            case 0 { revert(0, returndatasize()) }
            default { return(0, returndatasize()) }
        }
    }
}
设置
{
  "compilationTarget": {
    "xAAVEProxy.sol": "xAAVEProxy"
  },
  "evmVersion": "istanbul",
  "libraries": {},
  "metadata": {
    "bytecodeHash": "ipfs"
  },
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "remappings": []
}
ABI
[{"inputs":[{"internalType":"address","name":"implementation","type":"address"},{"internalType":"address","name":"proxyAdmin","type":"address"},{"internalType":"address","name":"signer1","type":"address"},{"internalType":"address","name":"signer2","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"stateMutability":"payable","type":"fallback"},{"inputs":[],"name":"confirmAdminTransfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"confirmedImplementation","type":"address"}],"name":"confirmImplementation","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"implementation","outputs":[{"internalType":"address","name":"impl","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newAdminAddress","type":"address"}],"name":"proposeAdminTransfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newImplementation","type":"address"}],"name":"proposeNewImplementation","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"proposedNewAdmin","outputs":[{"internalType":"address","name":"newAdmin","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"proposedNewAdminTimestamp","outputs":[{"internalType":"uint256","name":"timestamp","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"proposedNewImplementation","outputs":[{"internalType":"address","name":"impl","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"proxyAdmin","outputs":[{"internalType":"address","name":"admin","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"proxySigner","outputs":[{"internalType":"address","name":"signer","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"proxyType","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"}]