Cryo Explorer Ethereum Mainnet

Address Contract Verified

Address 0xca33105902E8d232DDFb9f71Ff3D79C7E7f2C4e5
Balance 0 ETH
Nonce 11
Code Size 7649 bytes
Indexed Transactions 0
External Etherscan · Sourcify

Contract Bytecode

7649 bytes
0x60806040523480156200001157600080fd5b5060043610620001155760003560e01c80638636f07e11620000a3578063b4e6747f116200006e578063b4e6747f14620002a0578063cc2e0a2614620002b7578063d867e0de14620002ce578063fe69f70814620002ff57600080fd5b80638636f07e1462000225578063881829121462000251578063b28317bf1462000268578063b39c4593146200027f57600080fd5b80633a60339a11620000e45780633a60339a14620001ac578063517b657f14620001c05780636b44e6be14620001d757806385b8a52f146200020e57600080fd5b80630db3ff45146200011a5780630e6e4b25146200015957806312700bae14620001895780631798d48214620001a2575b600080fd5b620001466200012b36600462001865565b6001600160a01b031660009081526001602052604090205490565b6040519081526020015b60405180910390f35b620001706200016a366004620018c9565b62000316565b6040516001600160a01b03909116815260200162000150565b620001a06200019a36600462001933565b62000359565b005b6200014660045481565b60035462000170906001600160a01b031681565b62000170620001d1366004620018c9565b62000562565b620001fd620001e836600462001865565b60056020526000908152604090205460ff1681565b604051901515815260200162000150565b620001706200021f366004620019ca565b6200066c565b620001706200023636600462001919565b6000908152602081905260409020546001600160a01b031690565b620001a062000262366004620019ca565b62000696565b620001a062000279366004620019ed565b62000842565b6004546000908152602081905260409020546001600160a01b031662000170565b620001a0620002b136600462001919565b620009fc565b620001a0620002c836600462001865565b62000b5e565b620001fd620002df366004620019ca565b600660209081526000928352604080842090915290825290205460ff1681565b620001a0620003103660046200197a565b62000d37565b60006200034f848484604051602001620003339392919062001a1e565b6040516020818303038152906040528051906020012062000fc9565b90505b9392505050565b600360009054906101000a90046001600160a01b03166001600160a01b0316630c340a246040518163ffffffff1660e01b815260040160206040518083038186803b158015620003a857600080fd5b505afa158015620003bd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620003e3919062001885565b6001600160a01b0316336001600160a01b0316146200041f5760405162461bcd60e51b8152600401620004169062001af4565b60405180910390fd5b82620004675760405162461bcd60e51b815260206004820152601660248201527526a8231d29249d24a72b20a624a22fab22a929a4a7a760511b604482015260640162000416565b806001600160a01b0316826001600160a01b0316847fe69962526b7f07862bf85663f861564361295f9601236fbbe056591eb1b63f3b60405160405180910390a4620004b48383620010a4565b620005025760405162461bcd60e51b815260206004820152601e60248201527f4d50463a52493a4641494c5f464f525f494d504c454d454e544154494f4e0000604482015260640162000416565b6200050f83848362001150565b6200055d5760405162461bcd60e51b815260206004820152601860248201527f4d50463a52493a4641494c5f464f525f4d49475241544f520000000000000000604482015260640162000416565b505050565b60035460405163569e0d2960e01b81523360048201526000916001600160a01b03169063569e0d299060240160206040518083038186803b158015620005a757600080fd5b505afa158015620005bc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620005e29190620018a5565b620006275760405162461bcd60e51b8152602060048201526014602482015273574d463a43493a43414e4e4f545f4445504c4f5960601b604482015260640162000416565b6001600560006200063a878787620011da565b6001600160a01b03811682526020820192909252604001600020805460ff191692151592909217909155949350505050565b60008281526002602090815260408083208484529091529020546001600160a01b03165b92915050565b600360009054906101000a90046001600160a01b03166001600160a01b0316630c340a246040518163ffffffff1660e01b815260040160206040518083038186803b158015620006e557600080fd5b505afa158015620006fa573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000720919062001885565b6001600160a01b0316336001600160a01b031614620007535760405162461bcd60e51b8152600401620004169062001af4565b80821415620007a55760405162461bcd60e51b815260206004820152601f60248201527f4d50463a4455503a4f56455257524954494e475f494e495449414c495a455200604482015260640162000416565b620007b38282600062001150565b620007f25760405162461bcd60e51b815260206004820152600e60248201526d1354118e9115540e91905253115160921b604482015260640162000416565b604051819083907fa46f1addc2236b7d93ed2a8a507f1c47cc92656d2b6f82bf0876da9e964b9e5e90600090a360009182526006602090815260408084209284529190529020805460ff19169055565b600360009054906101000a90046001600160a01b03166001600160a01b0316630c340a246040518163ffffffff1660e01b815260040160206040518083038186803b1580156200089157600080fd5b505afa158015620008a6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620008cc919062001885565b6001600160a01b0316336001600160a01b031614620008ff5760405162461bcd60e51b8152600401620004169062001af4565b81831415620009515760405162461bcd60e51b815260206004820152601f60248201527f4d50463a4555503a4f56455257524954494e475f494e495449414c495a455200604482015260640162000416565b6200095e83838362001150565b6200099d5760405162461bcd60e51b815260206004820152600e60248201526d1354118e9155540e91905253115160921b604482015260640162000416565b806001600160a01b031682847f549a41e54b51dcc3f29b51bb02a8adcc4ec5ae26604608e41bde60311dcef10660405160405180910390a45060009182526006602090815260408084209284529190529020805460ff19166001179055565b600360009054906101000a90046001600160a01b03166001600160a01b0316630c340a246040518163ffffffff1660e01b815260040160206040518083038186803b15801562000a4b57600080fd5b505afa15801562000a60573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000a86919062001885565b6001600160a01b0316336001600160a01b03161462000ab95760405162461bcd60e51b8152600401620004169062001af4565b80158062000add57506000818152602081905260409020546001600160a01b031615155b62000b2b5760405162461bcd60e51b815260206004820152601760248201527f4d50463a5344563a494e56414c49445f56455253494f4e000000000000000000604482015260640162000416565b600481905560405181907fddb2013cf7f102d15447c4c1e94cf56823455f02eb244d0c3b2ef6516338934690600090a250565b600360009054906101000a90046001600160a01b03166001600160a01b0316630c340a246040518163ffffffff1660e01b815260040160206040518083038186803b15801562000bad57600080fd5b505afa15801562000bc2573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000be8919062001885565b6001600160a01b0316336001600160a01b03161462000c1b5760405162461bcd60e51b8152600401620004169062001af4565b60006001600160a01b0316816001600160a01b0316630c340a246040518163ffffffff1660e01b815260040160206040518083038186803b15801562000c6057600080fd5b505afa15801562000c75573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000c9b919062001885565b6001600160a01b0316141562000ced5760405162461bcd60e51b81526020600482015260166024820152754d50463a53473a494e56414c49445f474c4f42414c5360501b604482015260640162000416565b600380546001600160a01b0319166001600160a01b0383169081179091556040517f9074839b84a74138be159cb7813a72c2a44c35fe8c53da66a16da385d348c5f190600090a250565b600360009054906101000a90046001600160a01b03166001600160a01b031663425fad586040518163ffffffff1660e01b815260040160206040518083038186803b15801562000d8657600080fd5b505afa15801562000d9b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000dc19190620018a5565b1562000e065760405162461bcd60e51b81526020600482015260136024820152721354118e941493d513d0d3d317d4105554d151606a1b604482015260640162000416565b600060016000336001600160a01b0316635c60da1b6040518163ffffffff1660e01b815260040160206040518083038186803b15801562000e4657600080fd5b505afa15801562000e5b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000e81919062001885565b6001600160a01b03168152602080820192909252604090810160009081205480825260068452828220888352909352205490915060ff1662000efb5760405162461bcd60e51b81526020600482015260126024820152711354118e95524e9393d517d0531313d5d15160721b604482015260640162000416565b8381336001600160a01b03167ffbb4f36b70dba8ecedc8b38361f44f1b0c61e04ec4e0ccf620649dc558573f5f868660405162000f3a92919062001ac5565b60405180910390a462000f85338585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250620013bd92505050565b62000fc35760405162461bcd60e51b815260206004820152600d60248201526c1354118e95524e919052531151609a1b604482015260640162000416565b50505050565b600060ff60f81b30836040518060200162000fe4906200180b565b601f1982820381018352601f90910116604081815230602083015260009082015260600160408051601f198184030181529082905262001028929160200162001a4e565b604051602081830303815290604052805190602001206040516020016200108694939291906001600160f81b031994909416845260609290921b6bffffffffffffffffffffffff191660018401526015830152603582015260550190565b60408051601f19818403018152919052805160209091012092915050565b6000821580620010ca57506000838152602081905260409020546001600160a01b031615155b80620010ed57506001600160a01b03821660009081526001602052604090205415155b806200110157506001600160a01b0382163b155b15620011105750600062000690565b5060008281526020818152604080832080546001600160a01b0319166001600160a01b039590951694851790559282526001908190529190209190915590565b60008315806200115e575082155b156200116d5750600062000352565b6001600160a01b038216158015906200118e57506001600160a01b0382163b155b156200119d5750600062000352565b506000928352600260209081526040808520938552929052912080546001600160a01b0319166001600160a01b0392909216919091179055600190565b6003546040805163084bf5ab60e31b815290516000926001600160a01b03169163425fad58916004808301926020929190829003018186803b1580156200122057600080fd5b505afa15801562001235573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200125b9190620018a5565b15620012a05760405162461bcd60e51b81526020600482015260136024820152721354118e941493d513d0d3d317d4105554d151606a1b604482015260640162000416565b60006200130f85858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604051620012f392508991508890889060200162001a1e565b60405160208183030381529060405280519060200120620015d5565b9250905080620013525760405162461bcd60e51b815260206004820152600d60248201526c1354118e90d24e919052531151609a1b604482015260640162000416565b6001600160a01b03821660008181526005602052604090819020805460ff1916600117905560045490517f8919387fe006fdc29a3dfcc183071d7974bc03747fedb0019630f1e13f85cc6490620013ad908990899062001ac5565b60405180910390a3509392505050565b60006001600160a01b0384163b620013d85750600062000352565b6000838152602081905260409020546001600160a01b0316806200140157600091505062000352565b60006200140e8662001673565b909350905082620014255760009250505062000352565b604080516001600160a01b0384811660248084019190915283518084039091018152604490920183526020820180516001600160e01b0316636bc26a1360e11b1790529151918816916200147a919062001a30565b6000604051808303816000865af19150503d8060008114620014b9576040519150601f19603f3d011682016040523d82523d6000602084013e620014be565b606091505b50508093505082620014d65760009250505062000352565b6001600160a01b0380821660009081526001602090815260408083205483526002825280832089845290915290205416806200151c576000855114935050505062000352565b866001600160a01b031663c3fbb6fd60e01b82876040516024016200154392919062001a81565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252905162001583919062001a30565b6000604051808303816000865af19150503d8060008114620015c2576040519150601f19603f3d011682016040523d82523d6000602084013e620015c7565b606091505b509098975050505050505050565b60008082306000604051620015ea906200180b565b6001600160a01b039283168152911660208201526040018190604051809103906000f590508015801562001622573d6000803e3d6000fd5b5090506000620016328262001673565b6001600160a01b038116600090815260016020526040902054909250905080158015906200166857506200166883828862001723565b935050509250929050565b60408051600481526024810182526020810180516001600160e01b0316635c60da1b60e01b179052905160009182916060916001600160a01b03861691620016bc919062001a30565b600060405180830381855afa9150503d8060008114620016f9576040519150601f19603f3d011682016040523d82523d6000602084013e620016fe565b606091505b50805191945091506200171b908201602090810190830162001885565b915050915091565b60008281526002602090815260408083209091528120546001600160a01b0316806200175457505080511562000352565b846001600160a01b031663c3fbb6fd60e01b82856040516024016200177b92919062001a81565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b0319909416939093179092529051620017bb919062001a30565b6000604051808303816000865af19150503d8060008114620017fa576040519150601f19603f3d011682016040523d82523d6000602084013e620017ff565b606091505b50909695505050505050565b6102458062001b6783390190565b60008083601f8401126200182c57600080fd5b50813567ffffffffffffffff8111156200184557600080fd5b6020830191508360208285010111156200185e57600080fd5b9250929050565b6000602082840312156200187857600080fd5b8135620003528162001b4d565b6000602082840312156200189857600080fd5b8151620003528162001b4d565b600060208284031215620018b857600080fd5b815180151581146200035257600080fd5b600080600060408486031215620018df57600080fd5b833567ffffffffffffffff811115620018f757600080fd5b620019058682870162001819565b909790965060209590950135949350505050565b6000602082840312156200192c57600080fd5b5035919050565b6000806000606084860312156200194957600080fd5b8335925060208401356200195d8162001b4d565b915060408401356200196f8162001b4d565b809150509250925092565b6000806000604084860312156200199057600080fd5b83359250602084013567ffffffffffffffff811115620019af57600080fd5b620019bd8682870162001819565b9497909650939450505050565b60008060408385031215620019de57600080fd5b50508035926020909101359150565b60008060006060848603121562001a0357600080fd5b833592506020840135915060408401356200196f8162001b4d565b82848237909101908152602001919050565b6000825162001a4481846020870162001b1e565b9190910192915050565b6000835162001a6281846020880162001b1e565b83519083019062001a7881836020880162001b1e565b01949350505050565b60018060a01b0383168152604060208201526000825180604084015262001ab081606085016020870162001b1e565b601f01601f1916919091016060019392505050565b60208152816020820152818360408301376000818301604090810191909152601f909201601f19160101919050565b60208082526010908201526f26a8231d2727aa2fa3a7ab22a92727a960811b604082015260600190565b60005b8381101562001b3b57818101518382015260200162001b21565b8381111562000fc35750506000910152565b6001600160a01b038116811462001b6357600080fd5b5056fe608060405234801561001057600080fd5b5060405161024538038061024583398101604081905261002f91610169565b6001600160a01b0382167f7a45a402e4cb6e08ebc196f20f66d5d30e67285a2a8aa80503fa409e727a4af15560006001600160a01b0382161561007257816100e3565b826001600160a01b031663b39c45936040518163ffffffff1660e01b815260040160206040518083038186803b1580156100ab57600080fd5b505afa1580156100bf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100e39190610147565b90506001600160a01b0381166100f857600080fd5b6001600160a01b03167f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc555061019c9050565b80516001600160a01b038116811461014257600080fd5b919050565b60006020828403121561015957600080fd5b6101628261012b565b9392505050565b6000806040838503121561017c57600080fd5b6101858361012b565b91506101936020840161012b565b90509250929050565b609b806101aa6000396000f3fe60806040526000602d7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b90506001600160a01b0381163b604257600080fd5b3660008037600080366000845af43d6000803e8080156060573d6000f35b3d6000fdfea2646970667358221220c8872fc7fbfd8b65110f1223c01eeccb9f4a10ea824be092efdc9476b129c14964736f6c63430008070033a2646970667358221220851250b825f6450953ce2034d49c22a0862f251583286524d8a6503369c742e564736f6c63430008070033

Verified Source Code Full Match

Compiler: v0.8.7+commit.e28d00a7 EVM: london Optimization: Yes (200 runs)
Interfaces.sol 67 lines
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.7;

interface IERC20Like {

    function balanceOf(address account_) external view returns (uint256 balance_);

}

interface IGlobalsLike {

    function canDeploy(address caller_) external view returns (bool canDeploy_);

    function isFunctionPaused(bytes4 sig_) external view returns (bool isFunctionPaused_);

    function governor() external view returns (address governor_);

    function isInstanceOf(bytes32 instanceId, address instance_) external view returns (bool isInstance_);

    function isValidScheduledCall(
        address caller_,
        address contract_,
        bytes32 functionId_,
        bytes calldata callData_
    ) external view returns (bool isValid_);

    function operationalAdmin() external view returns (address operationalAdmin_);

    function securityAdmin() external view returns (address securityAdmin_);

    function unscheduleCall(address caller_, bytes32 functionId_, bytes calldata callData_) external;

}

interface IMapleProxyFactoryLike {

    function isInstance(address instance_) external view returns (bool isInstance_);

    function mapleGlobals() external returns (address globals_);

}

interface IPoolLike {

    function asset() external view returns (address asset_);

    function manager() external view returns (address poolManager_);

    function previewRedeem(uint256 shares_) external view returns (uint256 assets_);

    function redeem(uint256 shares_, address receiver_, address owner_) external returns (uint256 assets_);

    function totalSupply() external view returns (uint256 totalSupply_);

}

interface IPoolManagerLike {

    function factory() external view returns (address factory_);

    function poolDelegate() external view returns (address poolDelegate_);

    function totalAssets() external view returns (uint256 totalAssets_);

    function unrealizedLosses() external view returns (uint256 unrealizedLosses_);

}
MapleWithdrawalManagerFactory.sol 23 lines
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.7;

import { MapleProxyFactory } from "../../modules/maple-proxy-factory/contracts/MapleProxyFactory.sol";

import { IGlobalsLike } from "../interfaces/Interfaces.sol";

contract MapleWithdrawalManagerFactory is MapleProxyFactory {

    constructor(address globals_) MapleProxyFactory(globals_) {}

    function createInstance(
        bytes calldata arguments_,
        bytes32 salt_
    )
        public override(MapleProxyFactory) returns (address instance_)
    {
        require(IGlobalsLike(mapleGlobals).canDeploy(msg.sender), "WMF:CI:CANNOT_DEPLOY");

        isInstance[instance_ = super.createInstance(arguments_, salt_)] = true;
    }

}
MapleProxyFactory.sol 135 lines
// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity 0.8.7;

import { ProxyFactory } from "../modules/proxy-factory/contracts/ProxyFactory.sol";

import { IMapleGlobalsLike }  from "./interfaces/Interfaces.sol";
import { IMapleProxied }      from "./interfaces/IMapleProxied.sol";
import { IMapleProxyFactory } from "./interfaces/IMapleProxyFactory.sol";

/// @title A Maple factory for Proxy contracts that proxy MapleProxied implementations.
contract MapleProxyFactory is IMapleProxyFactory, ProxyFactory {

    address public override mapleGlobals;

    uint256 public override defaultVersion;

    mapping(address => bool) public override isInstance;

    mapping(uint256 => mapping(uint256 => bool)) public override upgradeEnabledForPath;

    constructor(address mapleGlobals_) {
        require(IMapleGlobalsLike(mapleGlobals = mapleGlobals_).governor() != address(0), "MPF:C:INVALID_GLOBALS");
    }

    modifier onlyGovernor() {
        require(msg.sender == IMapleGlobalsLike(mapleGlobals).governor(), "MPF:NOT_GOVERNOR");
        _;
    }

    modifier whenProtocolNotPaused() {
        require(!IMapleGlobalsLike(mapleGlobals).protocolPaused(), "MPF:PROTOCOL_PAUSED");
        _;
    }

    /**************************************************************************************************************************************/
    /*** Admin Functions                                                                                                                ***/
    /**************************************************************************************************************************************/

    function disableUpgradePath(uint256 fromVersion_, uint256 toVersion_) public override virtual onlyGovernor {
        require(fromVersion_ != toVersion_,                              "MPF:DUP:OVERWRITING_INITIALIZER");
        require(_registerMigrator(fromVersion_, toVersion_, address(0)), "MPF:DUP:FAILED");

        emit UpgradePathDisabled(fromVersion_, toVersion_);

        upgradeEnabledForPath[fromVersion_][toVersion_] = false;
    }

    function enableUpgradePath(uint256 fromVersion_, uint256 toVersion_, address migrator_) public override virtual onlyGovernor {
        require(fromVersion_ != toVersion_,                             "MPF:EUP:OVERWRITING_INITIALIZER");
        require(_registerMigrator(fromVersion_, toVersion_, migrator_), "MPF:EUP:FAILED");

        emit UpgradePathEnabled(fromVersion_, toVersion_, migrator_);

        upgradeEnabledForPath[fromVersion_][toVersion_] = true;
    }

    function registerImplementation(uint256 version_, address implementationAddress_, address initializer_)
        public override virtual onlyGovernor
    {
        // Version 0 reserved as "no version" since default `defaultVersion` is 0.
        require(version_ != uint256(0), "MPF:RI:INVALID_VERSION");

        emit ImplementationRegistered(version_, implementationAddress_, initializer_);

        require(_registerImplementation(version_, implementationAddress_), "MPF:RI:FAIL_FOR_IMPLEMENTATION");

        // Set migrator for initialization, which understood as fromVersion == toVersion.
        require(_registerMigrator(version_, version_, initializer_), "MPF:RI:FAIL_FOR_MIGRATOR");
    }

    function setDefaultVersion(uint256 version_) public override virtual onlyGovernor {
        // Version must be 0 (to disable creating new instances) or be registered.
        require(version_ == 0 || _implementationOf[version_] != address(0), "MPF:SDV:INVALID_VERSION");

        emit DefaultVersionSet(defaultVersion = version_);
    }

    function setGlobals(address mapleGlobals_) public override virtual onlyGovernor {
        require(IMapleGlobalsLike(mapleGlobals_).governor() != address(0), "MPF:SG:INVALID_GLOBALS");

        emit MapleGlobalsSet(mapleGlobals = mapleGlobals_);
    }

    /**************************************************************************************************************************************/
    /*** Instance Functions                                                                                                             ***/
    /**************************************************************************************************************************************/

    function createInstance(bytes calldata arguments_, bytes32 salt_)
        public override virtual whenProtocolNotPaused returns (address instance_)
    {
        bool success;
        ( success, instance_ ) = _newInstance(arguments_, keccak256(abi.encodePacked(arguments_, salt_)));
        require(success, "MPF:CI:FAILED");

        isInstance[instance_] = true;

        emit InstanceDeployed(defaultVersion, instance_, arguments_);
    }

    // NOTE: The implementation proxied by the instance defines the access control logic for its own upgrade.
    function upgradeInstance(uint256 toVersion_, bytes calldata arguments_) public override virtual whenProtocolNotPaused {
        uint256 fromVersion = _versionOf[IMapleProxied(msg.sender).implementation()];

        require(upgradeEnabledForPath[fromVersion][toVersion_], "MPF:UI:NOT_ALLOWED");

        emit InstanceUpgraded(msg.sender, fromVersion, toVersion_, arguments_);

        require(_upgradeInstance(msg.sender, toVersion_, arguments_), "MPF:UI:FAILED");
    }

    /**************************************************************************************************************************************/
    /*** View Functions                                                                                                                 ***/
    /**************************************************************************************************************************************/

    function getInstanceAddress(bytes calldata arguments_, bytes32 salt_) public view override virtual returns (address instanceAddress_) {
        return _getDeterministicProxyAddress(keccak256(abi.encodePacked(arguments_, salt_)));
    }

    function implementationOf(uint256 version_) public view override virtual returns (address implementation_) {
        return _implementationOf[version_];
    }

    function defaultImplementation() external view override returns (address defaultImplementation_) {
        return _implementationOf[defaultVersion];
    }

    function migratorForPath(uint256 oldVersion_, uint256 newVersion_) public view override virtual returns (address migrator_) {
        return _migratorForPath[oldVersion_][newVersion_];
    }

    function versionOf(address implementation_) public view override virtual returns (uint256 version_) {
        return _versionOf[implementation_];
    }

}
Interfaces.sol 11 lines
// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity 0.8.7;

interface IMapleGlobalsLike {

    /// @dev The address of the Governor responsible for management of global Maple variables.
    function governor() external view returns (address governor_);

    function protocolPaused() external view returns (bool protocolPaused_);

}
IMapleProxied.sol 24 lines
// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity 0.8.7;

import { IProxied } from "../../modules/proxy-factory/contracts/interfaces/IProxied.sol";

/// @title A Maple implementation that is to be proxied, must implement IMapleProxied.
interface IMapleProxied is IProxied {

    /**
     *  @dev   The instance was upgraded.
     *  @param toVersion_ The new version of the loan.
     *  @param arguments_ The upgrade arguments, if any.
     */
    event Upgraded(uint256 toVersion_, bytes arguments_);

    /**
     *  @dev   Upgrades a contract implementation to a specific version.
     *         Access control logic critical since caller can force a selfdestruct via a malicious `migrator_` which is delegatecalled.
     *  @param toVersion_ The version to upgrade to.
     *  @param arguments_ Some encoded arguments to use for the upgrade.
     */
    function upgrade(uint256 toVersion_, bytes calldata arguments_) external;

}
Proxy.sol 59 lines
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity ^0.8.7;

import { IDefaultImplementationBeacon } from "./interfaces/IDefaultImplementationBeacon.sol";

import { SlotManipulatable } from "./SlotManipulatable.sol";

/// @title A completely transparent, and thus interface-less, proxy contract.
contract Proxy is SlotManipulatable {

    /// @dev Storage slot with the address of the current factory. `keccak256('eip1967.proxy.factory') - 1`.
    bytes32 private constant FACTORY_SLOT = bytes32(0x7a45a402e4cb6e08ebc196f20f66d5d30e67285a2a8aa80503fa409e727a4af1);

    /// @dev Storage slot with the address of the current factory. `keccak256('eip1967.proxy.implementation') - 1`.
    bytes32 private constant IMPLEMENTATION_SLOT = bytes32(0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc);

    /**
     *  @dev   The constructor requires at least one of `factory_` or `implementation_`.
     *         If an implementation is not provided, the factory is treated as an IDefaultImplementationBeacon
     *         to fetch the default implementation.
     *  @param factory_        The address of a proxy factory, if any.
     *  @param implementation_ The address of the implementation contract being proxied, if any.
     */
    constructor(address factory_, address implementation_) {
        _setSlotValue(FACTORY_SLOT, bytes32(uint256(uint160(factory_))));

        // If the implementation is empty, fetch it from the factory, which can act as a beacon.
        address implementation = implementation_ == address(0)
            ? IDefaultImplementationBeacon(factory_).defaultImplementation()
            : implementation_;

        require(implementation != address(0));

        _setSlotValue(IMPLEMENTATION_SLOT, bytes32(uint256(uint160(implementation))));
    }

    fallback() payable external virtual {
        bytes32 implementation = _getSlotValue(IMPLEMENTATION_SLOT);

        require(address(uint160(uint256(implementation))).code.length != uint256(0));

        assembly {
            calldatacopy(0, 0, calldatasize())

            let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)

            returndatacopy(0, 0, returndatasize())

            switch result
            case 0 {
                revert(0, returndatasize())
            }
            default {
                return(0, returndatasize())
            }
        }
    }

}
IMapleProxyFactory.sol 189 lines
// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity 0.8.7;

import { IDefaultImplementationBeacon } from "../../modules/proxy-factory/contracts/interfaces/IDefaultImplementationBeacon.sol";

/// @title A Maple factory for Proxy contracts that proxy MapleProxied implementations.
interface IMapleProxyFactory is IDefaultImplementationBeacon {

    /**************************************************************************************************************************************/
    /*** Events                                                                                                                         ***/
    /**************************************************************************************************************************************/

    /**
     *  @dev   A default version was set.
     *  @param version_ The default version.
     */
    event DefaultVersionSet(uint256 indexed version_);

    /**
     *  @dev   A version of an implementation, at some address, was registered, with an optional initializer.
     *  @param version_               The version registered.
     *  @param implementationAddress_ The address of the implementation.
     *  @param initializer_           The address of the initializer, if any.
     */
    event ImplementationRegistered(uint256 indexed version_, address indexed implementationAddress_, address indexed initializer_);

    /**
     *  @dev   A proxy contract was deployed with some initialization arguments.
     *  @param version_                 The version of the implementation being proxied by the deployed proxy contract.
     *  @param instance_                The address of the proxy contract deployed.
     *  @param initializationArguments_ The arguments used to initialize the proxy contract, if any.
     */
    event InstanceDeployed(uint256 indexed version_, address indexed instance_, bytes initializationArguments_);

    /**
     *  @dev   A instance has upgraded by proxying to a new implementation, with some migration arguments.
     *  @param instance_           The address of the proxy contract.
     *  @param fromVersion_        The initial implementation version being proxied.
     *  @param toVersion_          The new implementation version being proxied.
     *  @param migrationArguments_ The arguments used to migrate, if any.
     */
    event InstanceUpgraded(address indexed instance_, uint256 indexed fromVersion_, uint256 indexed toVersion_, bytes migrationArguments_);

    /**
     *  @dev   The MapleGlobals was set.
     *  @param mapleGlobals_ The address of a Maple Globals contract.
     */
    event MapleGlobalsSet(address indexed mapleGlobals_);

    /**
     *  @dev   An upgrade path was disabled, with an optional migrator contract.
     *  @param fromVersion_ The starting version of the upgrade path.
     *  @param toVersion_   The destination version of the upgrade path.
     */
    event UpgradePathDisabled(uint256 indexed fromVersion_, uint256 indexed toVersion_);

    /**
     *  @dev   An upgrade path was enabled, with an optional migrator contract.
     *  @param fromVersion_ The starting version of the upgrade path.
     *  @param toVersion_   The destination version of the upgrade path.
     *  @param migrator_    The address of the migrator, if any.
     */
    event UpgradePathEnabled(uint256 indexed fromVersion_, uint256 indexed toVersion_, address indexed migrator_);

    /**************************************************************************************************************************************/
    /*** State Variables                                                                                                                ***/
    /**************************************************************************************************************************************/

    /**
     *  @dev The default version.
     */
    function defaultVersion() external view returns (uint256 defaultVersion_);

    /**
     *  @dev The address of the MapleGlobals contract.
     */
    function mapleGlobals() external view returns (address mapleGlobals_);

    /**
     *  @dev    Whether the upgrade is enabled for a path from a version to another version.
     *  @param  toVersion_   The initial version.
     *  @param  fromVersion_ The destination version.
     *  @return allowed_     Whether the upgrade is enabled.
     */
    function upgradeEnabledForPath(uint256 toVersion_, uint256 fromVersion_) external view returns (bool allowed_);

    /**************************************************************************************************************************************/
    /*** State Changing Functions                                                                                                       ***/
    /**************************************************************************************************************************************/

    /**
     *  @dev    Deploys a new instance proxying the default implementation version, with some initialization arguments.
     *          Uses a nonce and `msg.sender` as a salt for the CREATE2 opcode during instantiation to produce deterministic addresses.
     *  @param  arguments_ The initialization arguments to use for the instance deployment, if any.
     *  @param  salt_      The salt to use in the contract creation process.
     *  @return instance_  The address of the deployed proxy contract.
     */
    function createInstance(bytes calldata arguments_, bytes32 salt_) external returns (address instance_);

    /**
     *  @dev   Enables upgrading from a version to a version of an implementation, with an optional migrator.
     *         Only the Governor can call this function.
     *  @param fromVersion_ The starting version of the upgrade path.
     *  @param toVersion_   The destination version of the upgrade path.
     *  @param migrator_    The address of the migrator, if any.
     */
    function enableUpgradePath(uint256 fromVersion_, uint256 toVersion_, address migrator_) external;

    /**
     *  @dev   Disables upgrading from a version to a version of a implementation.
     *         Only the Governor can call this function.
     *  @param fromVersion_ The starting version of the upgrade path.
     *  @param toVersion_   The destination version of the upgrade path.
     */
    function disableUpgradePath(uint256 fromVersion_, uint256 toVersion_) external;

    /**
     *  @dev   Registers the address of an implementation contract as a version, with an optional initializer.
     *         Only the Governor can call this function.
     *  @param version_               The version to register.
     *  @param implementationAddress_ The address of the implementation.
     *  @param initializer_           The address of the initializer, if any.
     */
    function registerImplementation(uint256 version_, address implementationAddress_, address initializer_) external;

    /**
     *  @dev   Sets the default version.
     *         Only the Governor can call this function.
     *  @param version_ The implementation version to set as the default.
     */
    function setDefaultVersion(uint256 version_) external;

    /**
     *  @dev   Sets the Maple Globals contract.
     *         Only the Governor can call this function.
     *  @param mapleGlobals_ The address of a Maple Globals contract.
     */
    function setGlobals(address mapleGlobals_) external;

    /**
     *  @dev   Upgrades the calling proxy contract's implementation, with some migration arguments.
     *  @param toVersion_ The implementation version to upgrade the proxy contract to.
     *  @param arguments_ The migration arguments, if any.
     */
    function upgradeInstance(uint256 toVersion_, bytes calldata arguments_) external;

    /**************************************************************************************************************************************/
    /*** View Functions                                                                                                                 ***/
    /**************************************************************************************************************************************/

    /**
     *  @dev    Returns the deterministic address of a potential proxy, given some arguments and salt.
     *  @param  arguments_       The initialization arguments to be used when deploying the proxy.
     *  @param  salt_            The salt to be used when deploying the proxy.
     *  @return instanceAddress_ The deterministic address of a potential proxy.
     */
    function getInstanceAddress(bytes calldata arguments_, bytes32 salt_) external view returns (address instanceAddress_);

    /**
     *  @dev    Returns the address of an implementation version.
     *  @param  version_        The implementation version.
     *  @return implementation_ The address of the implementation.
     */
    function implementationOf(uint256 version_) external view returns (address implementation_);

    /**
     *  @dev    Returns if a given address has been deployed by this factory/
     *  @param  instance_   The address to check.
     *  @return isInstance_ A boolean indication if the address has been deployed by this factory.
     */
    function isInstance(address instance_) external view returns (bool isInstance_);

    /**
     *  @dev    Returns the address of a migrator contract for a migration path (from version, to version).
     *          If oldVersion_ == newVersion_, the migrator is an initializer.
     *  @param  oldVersion_ The old version.
     *  @param  newVersion_ The new version.
     *  @return migrator_   The address of a migrator contract.
     */
    function migratorForPath(uint256 oldVersion_, uint256 newVersion_) external view returns (address migrator_);

    /**
     *  @dev    Returns the version of an implementation contract.
     *  @param  implementation_ The address of an implementation contract.
     *  @return version_        The version of the implementation contract.
     */
    function versionOf(address implementation_) external view returns (uint256 version_);

}
ProxyFactory.sol 152 lines
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity ^0.8.7;

import { IProxied } from "./interfaces/IProxied.sol";

import { Proxy } from "./Proxy.sol";

/// @title A factory for Proxy contracts that proxy Proxied implementations.
abstract contract ProxyFactory {

    mapping(uint256 => address) internal _implementationOf;

    mapping(address => uint256) internal _versionOf;

    mapping(uint256 => mapping(uint256 => address)) internal _migratorForPath;

    /// @dev Returns the implementation of `proxy_`.
    function _getImplementationOfProxy(address proxy_) private view returns (bool success_, address implementation_) {
        bytes memory returnData;
        // Since `_getImplementationOfProxy` is a private function, no need to check `proxy_` is a contract.
        ( success_, returnData ) = proxy_.staticcall(abi.encodeWithSelector(IProxied.implementation.selector));
        implementation_ = abi.decode(returnData, (address));
    }

    /// @dev Initializes `proxy_` using the initializer for `version_`, given some initialization arguments.
    function _initializeInstance(address proxy_, uint256 version_, bytes memory arguments_) private returns (bool success_) {
        // The migrator, where fromVersion == toVersion, is an initializer.
        address initializer = _migratorForPath[version_][version_];

        // If there is no initializer, then no initialization is necessary, so long as no initialization arguments were provided.
        if (initializer == address(0)) return arguments_.length == uint256(0);

        // Call the migrate function on the proxy, passing any initialization arguments.
        // Since `_initializeInstance` is a private function, no need to check `proxy_` is a contract.
        ( success_, ) = proxy_.call(abi.encodeWithSelector(IProxied.migrate.selector, initializer, arguments_));
    }

    /// @dev Deploys a new proxy for some version, with some initialization arguments,
    ///      using `create` (i.e. factory's nonce determines the address).
    function _newInstance(uint256 version_, bytes memory arguments_) internal virtual returns (bool success_, address proxy_) {
        address implementation = _implementationOf[version_];

        if (implementation == address(0)) return (false, address(0));

        proxy_   = address(new Proxy(address(this), implementation));
        success_ = _initializeInstance(proxy_, version_, arguments_);
    }

    /// @dev Deploys a new proxy, with some initialization arguments, using `create2` (i.e. salt determines the address).
    ///      This factory needs to be IDefaultImplementationBeacon, since the proxy will pull its implementation from it.
    function _newInstance(bytes memory arguments_, bytes32 salt_) internal virtual returns (bool success_, address proxy_) {
        proxy_ = address(new Proxy{ salt: salt_ }(address(this), address(0)));

        // Fetch the implementation from the proxy. Don't care about success,
        // since the version of the implementation will be checked in the next step.
        ( , address implementation ) = _getImplementationOfProxy(proxy_);

        // Get the version of the implementation.
        uint256 version = _versionOf[implementation];

        // Successful if version is nonzero (i.e. implementation fetched successfully from proxy) and initializing the instance succeeds.
        success_ = (version != uint256(0)) && _initializeInstance(proxy_, version, arguments_);
    }

    /// @dev Registers an implementation for some version.
    function _registerImplementation(uint256 version_, address implementation_) internal virtual returns (bool success_) {
        // Version 0 is not allowed since its the default value of all _versionOf[implementation_].
        // Implementation cannot already be registered and cannot be empty account (and thus also not address(0)).
        if (
            version_ == uint256(0) ||
            _implementationOf[version_] != address(0) ||
            _versionOf[implementation_] != uint256(0) ||
            !_isContract(implementation_)
        ) return false;

        // Store in two-way mappings.
        _implementationOf[version_] = implementation_;
        _versionOf[implementation_] = version_;

        return true;
    }

    /// @dev Registers a migrator for between two versions. If `fromVersion_ == toVersion_`, migrator is an initializer.
    function _registerMigrator(uint256 fromVersion_, uint256 toVersion_, address migrator_) internal virtual returns (bool success_) {
        // Version 0 is invalid.
        if (fromVersion_ == uint256(0) || toVersion_ == uint256(0)) return false;

        // Migrator must either be zero (clearing) or a contract (setting).
        if (migrator_ != address(0) && !_isContract(migrator_)) return false;

        _migratorForPath[fromVersion_][toVersion_] = migrator_;

        return true;
    }

    /// @dev Upgrades a proxy to a new version of an implementation, with some migration arguments.
    ///      Inheritor should revert on `success_ = false`, since proxy can be set to new implementation, but failed to migrate.
    function _upgradeInstance(address proxy_, uint256 toVersion_, bytes memory arguments_) internal virtual returns (bool success_) {
        // Check that the proxy is currently a contract, just once, ahead of the 3 times it will be low-level-called.
        if (!_isContract(proxy_)) return false;

        address toImplementation = _implementationOf[toVersion_];

        // The implementation being migrated must have been registered (which also implies that `toVersion_` was not 0).
        if (toImplementation == address(0)) return false;

        // Fetch the implementation from the proxy.
        address fromImplementation;
        ( success_, fromImplementation ) = _getImplementationOfProxy(proxy_);

        if (!success_) return false;

        // Set the proxy's implementation.
        ( success_, ) = proxy_.call(abi.encodeWithSelector(IProxied.setImplementation.selector, toImplementation));

        if (!success_) return false;

        // Get the version of the `fromImplementation`, then get the `migrator` of the upgrade path to `toVersion_`.
        address migrator = _migratorForPath[_versionOf[fromImplementation]][toVersion_];

        // If there is no migrator, then no migration is necessary, so long as no migration arguments were provided.
        if (migrator == address(0)) return arguments_.length == uint256(0);

        // Call the migrate function on the proxy, passing any migration arguments.
        ( success_, ) = proxy_.call(abi.encodeWithSelector(IProxied.migrate.selector, migrator, arguments_));
    }

    /// @dev Returns the deterministic address of a proxy given some salt.
    function _getDeterministicProxyAddress(bytes32 salt_) internal virtual view returns (address deterministicProxyAddress_) {
        // See https://docs.soliditylang.org/en/v0.8.7/control-structures.html#salted-contract-creations-create2
        return address(
            uint160(
                uint256(
                    keccak256(
                        abi.encodePacked(
                            bytes1(0xff),
                            address(this),
                            salt_,
                            keccak256(abi.encodePacked(type(Proxy).creationCode, abi.encode(address(this), address(0))))
                        )
                    )
                )
            )
        );
    }

    /// @dev Returns whether the account is currently a contract.
    function _isContract(address account_) internal view returns (bool isContract_) {
        return account_.code.length != uint256(0);
    }

}
SlotManipulatable.sol 22 lines
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity ^0.8.7;

abstract contract SlotManipulatable {

    function _getReferenceTypeSlot(bytes32 slot_, bytes32 key_) internal pure returns (bytes32 value_) {
        return keccak256(abi.encodePacked(key_, slot_));
    }

    function _getSlotValue(bytes32 slot_) internal view returns (bytes32 value_) {
        assembly {
            value_ := sload(slot_)
        }
    }

    function _setSlotValue(bytes32 slot_, bytes32 value_) internal {
        assembly {
            sstore(slot_, value_)
        }
    }

}
IProxied.sol 31 lines
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity ^0.8.7;

/// @title An implementation that is to be proxied, must implement IProxied.
interface IProxied {

    /**
     *  @dev The address of the proxy factory.
     */
    function factory() external view returns (address factory_);

    /**
     *  @dev The address of the implementation contract being proxied.
     */
    function implementation() external view returns (address implementation_);

    /**
     *  @dev   Modifies the proxy's implementation address.
     *  @param newImplementation_ The address of an implementation contract.
     */
    function setImplementation(address newImplementation_) external;

    /**
     *  @dev   Modifies the proxy's storage by delegate-calling a migrator contract with some arguments.
     *         Access control logic critical since caller can force a selfdestruct via a malicious `migrator_` which is delegatecalled.
     *  @param migrator_  The address of a migrator contract.
     *  @param arguments_ Some encoded arguments to use for the migration.
     */
    function migrate(address migrator_, bytes calldata arguments_) external;

}
IDefaultImplementationBeacon.sol 10 lines
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity ^0.8.7;

/// @title An beacon that provides a default implementation for proxies, must implement IDefaultImplementationBeacon.
interface IDefaultImplementationBeacon {

    /// @dev The address of an implementation for proxies.
    function defaultImplementation() external view returns (address defaultImplementation_);

}

Read Contract

defaultImplementation 0xb39c4593 → address
defaultVersion 0x1798d482 → uint256
getInstanceAddress 0x0e6e4b25 → address
implementationOf 0x8636f07e → address
isInstance 0x6b44e6be → bool
mapleGlobals 0x3a60339a → address
migratorForPath 0x85b8a52f → address
upgradeEnabledForPath 0xd867e0de → bool
versionOf 0x0db3ff45 → uint256

Write Contract 7 functions

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

createInstance 0x517b657f
bytes arguments_
bytes32 salt_
returns: address
disableUpgradePath 0x88182912
uint256 fromVersion_
uint256 toVersion_
enableUpgradePath 0xb28317bf
uint256 fromVersion_
uint256 toVersion_
address migrator_
registerImplementation 0x12700bae
uint256 version_
address implementationAddress_
address initializer_
setDefaultVersion 0xb4e6747f
uint256 version_
setGlobals 0xcc2e0a26
address mapleGlobals_
upgradeInstance 0xfe69f708
uint256 toVersion_
bytes arguments_

Recent Transactions

No transactions found for this address