{"file_path":"src/protocol/ResupplyRegistry.sol","creation_status":"success","source_code":"// SPDX-License-Identifier: MIT\npragma solidity 0.8.28;\n\n/**\n * @title ResupplyRegistry\n * @notice Based on code from Drake Evans and Frax Finance's registry contract (https://github.com/FraxFinance/fraxlend), adapted for Resupply Finance\n */\n\nimport { CoreOwnable } from '../dependencies/CoreOwnable.sol';\nimport { IResupplyPair } from \"../interfaces/IResupplyPair.sol\";\nimport { IERC20Metadata } from \"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\";\nimport { IERC20 } from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport { SafeERC20 } from \"../libraries/SafeERC20.sol\";\nimport { IMintable } from \"../interfaces/IMintable.sol\";\nimport { IRewardHandler } from \"../interfaces/IRewardHandler.sol\";\n\ncontract ResupplyRegistry is CoreOwnable{\n    using SafeERC20 for IERC20;\n\n    // Protected keys\n    string public constant LIQUIDATION_HANDLER = \"LIQUIDATION_HANDLER\";\n    string public constant FEE_DEPOSIT = \"FEE_DEPOSIT\";\n    string public constant REDEMPTION_HANDLER = \"REDEMPTION_HANDLER\";\n    string public constant INSURANCE_POOL = \"INSURANCE_POOL\";\n    string public constant REWARD_HANDLER = \"REWARD_HANDLER\";\n    string public constant TREASURY = \"TREASURY\";\n    string public constant STAKER = \"STAKER\";\n    string public constant L2_MANAGER = \"L2_MANAGER\";\n    string public constant VEST_MANAGER = \"VEST_MANAGER\";\n\n    address public immutable token;\n    address public immutable govToken;\n\n    // protocol contracts\n    address public liquidationHandler;\n    address public feeDeposit;\n    address public redemptionHandler;\n    address public rewardHandler;\n    address public insurancePool;\n    address public staker;\n    address public treasury;\n    address public l2manager;\n    address public vestManager;\n    address[] public registeredPairs;\n    address[] public defaultSwappers;\n    string[] private keys; // Registry keys\n\n    mapping(string => address) public pairsByName;\n    mapping(string => address) private keyToAddress;\n    mapping(string => bool) public keyExists; // to prevent duplicate keys\n    mapping(bytes32 => string) public hashToKey;\n\n    constructor(address _core, address _token, address _govToken) CoreOwnable(_core){\n        token = _token;\n        govToken = _govToken;\n    }\n\n    event AddPair(address indexed pairAddress);\n    event DefaultSwappersSet(address[] addresses);\n    event EntryUpdated(string indexed key, address indexed addr);\n    event WithdrawTo(address indexed user, uint256 amount);\n\n    // ============================================================================================\n    // Functions: View Functions\n    // ============================================================================================\n\n    /// @notice The ```registeredPairsLength``` function returns the length of the registeredPairs\n    /// @return length of array\n    function registeredPairsLength() external view returns (uint256) {\n        return registeredPairs.length;\n    }\n\n    /// @notice The ```getAllPairAddresses``` function returns an array of all deployed pairs\n    /// @return _registeredPairs The array of pairs deployed\n    function getAllPairAddresses() external view returns (address[] memory _registeredPairs) {\n        _registeredPairs = registeredPairs;\n    }\n\n    // ============================================================================================\n    // Functions: Core Asset Registry\n    // ============================================================================================\n\n    function setL2Manager(address _newAddress) external onlyOwner{\n        l2manager = _newAddress;\n        _setAddress(_newAddress, L2_MANAGER, keccak256(bytes(L2_MANAGER)));\n    }\n\n    function setLiquidationHandler(address _newAddress) external onlyOwner{\n        liquidationHandler = _newAddress;\n        _setAddress(_newAddress, LIQUIDATION_HANDLER, keccak256(bytes(LIQUIDATION_HANDLER)));\n    }\n\n    function setFeeDeposit(address _newAddress) external onlyOwner{\n        feeDeposit = _newAddress;\n        _setAddress(_newAddress, FEE_DEPOSIT, keccak256(bytes(FEE_DEPOSIT)));\n    }\n\n    function setRedemptionHandler(address _newAddress) external onlyOwner{\n        redemptionHandler = _newAddress;\n        _setAddress(_newAddress, REDEMPTION_HANDLER, keccak256(bytes(REDEMPTION_HANDLER)));\n    }\n\n    function setInsurancePool(address _newAddress) external onlyOwner{\n        insurancePool = _newAddress;\n        _setAddress(_newAddress, INSURANCE_POOL, keccak256(bytes(INSURANCE_POOL)));\n    }\n\n    function setRewardHandler(address _newAddress) external onlyOwner{\n        rewardHandler = _newAddress;\n        _setAddress(_newAddress, REWARD_HANDLER, keccak256(bytes(REWARD_HANDLER)));\n    }\n\n    function setStaker(address _newAddress) external onlyOwner{\n        staker = _newAddress;\n        _setAddress(_newAddress, STAKER, keccak256(bytes(STAKER)));\n    }\n\n    function setTreasury(address _newAddress) external onlyOwner{\n        treasury = _newAddress;\n        _setAddress(_newAddress, TREASURY, keccak256(bytes(TREASURY)));\n    }\n\n    function setVestManager(address _newAddress) external onlyOwner{\n        vestManager = _newAddress;\n        _setAddress(_newAddress, VEST_MANAGER, keccak256(bytes(VEST_MANAGER)));\n    }\n\n    /// @notice The ```addPair``` function adds a pair to the registry and ensures a unique name\n    /// @param _pairAddress The address of the pair\n    function addPair(address _pairAddress) external onlyOwner{\n        // Add pair to the global list\n        registeredPairs.push(_pairAddress);\n\n        // Pull name, ensure uniqueness and add to the name mapping\n        string memory _name = IERC20Metadata(_pairAddress).name();\n        if (pairsByName[_name] != address(0)) revert NameMustBeUnique();\n        pairsByName[_name] = _pairAddress;\n\n        // Set additional values for ResupplyPair\n        IResupplyPair _pair = IResupplyPair(_pairAddress);\n        address[] memory _defaultSwappers = defaultSwappers;\n        for (uint256 i = 0; i < _defaultSwappers.length; i++) {\n            _pair.setSwapper(_defaultSwappers[i], true);\n        }\n\n        emit AddPair(_pairAddress);\n    }\n\n    /// @notice The ```setDefaultSwappers``` function is used to set default list of approved swappers\n    /// @param _swappers The list of swappers to set as default allowed\n    function setDefaultSwappers(address[] memory _swappers) external onlyOwner{\n        defaultSwappers = _swappers;\n        emit DefaultSwappersSet(_swappers);\n    }\n\n    // ============================================================================================\n    // Functions: Key Value Asset Registry\n    // ============================================================================================\n\n\n    /// @notice Generic address setter for the registry\n    /// @dev Cannot use for protected keys, since they are already assigned to specific variables\n    /// @param key The key to associate with the address\n    /// @param addr The address to store in the registry\n    function setAddress(string memory key, address addr) public onlyOwner {\n        bytes32 keyHash = keccak256(bytes(key));\n        // Check if key is protected\n        string[] memory protectedKeys = getProtectedKeys();\n        for (uint256 i = 0; i < protectedKeys.length; i++) {\n            if (keyHash == keccak256(bytes(protectedKeys[i]))) {\n                revert ProtectedKey(key);\n            }\n        }\n        _setAddress(addr, key, keyHash);\n    }\n\n    function _setAddress(address addr, string memory key, bytes32 keyHash) internal {\n        require(bytes(key).length > 0, \"Key cannot be empty\");\n        require(addr != address(0), \"Address cannot be zero\");\n        if (!keyExists[key]) {\n            hashToKey[keyHash] = key;\n            keys.push(key);\n            keyExists[key] = true;\n        }\n        keyToAddress[key] = addr;\n        emit EntryUpdated(key, addr);\n    }\n\n    function getAddress(string memory key) external view returns (address) {\n        return keyToAddress[key];\n    }\n\n    function getAllKeys() external view returns (string[] memory) {\n        return keys;\n    }\n\n    function getAllAddresses() external view returns (address[] memory) {\n        address[] memory addresses = new address[](keys.length);\n        uint256 len = keys.length;\n        for (uint i = 0; i < len; i++) {\n            addresses[i] = keyToAddress[keys[i]];\n        }\n        return addresses;\n    }\n\n    function getProtectedKeys() public pure returns (string[] memory) {\n        string[] memory _protectedKeys = new string[](9);\n        _protectedKeys[0] = LIQUIDATION_HANDLER;\n        _protectedKeys[1] = FEE_DEPOSIT;\n        _protectedKeys[2] = REDEMPTION_HANDLER;\n        _protectedKeys[3] = INSURANCE_POOL;\n        _protectedKeys[4] = REWARD_HANDLER;\n        _protectedKeys[5] = TREASURY;\n        _protectedKeys[6] = STAKER;\n        _protectedKeys[7] = L2_MANAGER;\n        _protectedKeys[8] = VEST_MANAGER;\n        return _protectedKeys;\n    }\n\n    // ============================================================================================\n    // Functions: Operations\n    // ============================================================================================\n\n    function withdrawTo(address _asset, uint256 _amount, address _to) external onlyOwner {\n        IERC20(_asset).safeTransfer(_to, _amount);\n        emit WithdrawTo(_to, _amount);\n    }\n\n    function mint(address _receiver, uint256 _amount) external {\n        require(pairsByName[IERC20Metadata(msg.sender).name()] == msg.sender, \"!regPair\");\n        IMintable(token).mint(_receiver, _amount);\n    }\n\n    function claimFees(address _pair) external {\n        require(pairsByName[IERC20Metadata(_pair).name()] == _pair, \"!regPair\");\n        IResupplyPair(_pair).withdrawFees();\n    }\n\n    function claimRewards(address _pair) external {\n        IRewardHandler(rewardHandler).claimRewards(_pair);\n    }\n\n    function claimInsuranceRewards() external {\n        IRewardHandler(rewardHandler).claimInsuranceRewards();\n    }\n\n    // ============================================================================================\n    // Errors\n    // ============================================================================================\n\n    error NameMustBeUnique();\n    error ProtectedKey(string key);\n}\n","deployed_bytecode":"0x60806040526004361015610011575f80fd5b5f5f3560e01c806302be459e1461172057806305268cff146116dc57806315a0ea6a146115ff57806316510108146115855780631deee6121461150a57806323103b7d146114ed57806326e53399146114d25780632d2c5565146114b757806340c10f191461139e57806345c881a01461138257806357e3e8d31461130657806358537ca9146112aa5780635baffe8e1461128e5780635cdcfadf146112635780635ebaf1db1461123a578063607b6d16146111b057806361d027b314611187578063670fb8211461115e57806369285727146110f05780636c191eee14610f415780637a883d6e14610ec557806382aa4e0614610e495780638387832514610e2d5780638413aec714610dca5780638da5cb5b146102875780639516a10414610cba57806397cb6a4414610c6c5780639b2ea4bd14610b805780639efc920814610b04578063a13aed1f14610ae8578063a29a43bb14610a6c578063a94c487e146109f0578063ab2adc00146109c7578063abca72901461099e578063b0df4cab14610982578063b1fc70081461093e578063bc87eed3146108b4578063bf40fac114610851578063bff59f8f14610821578063c1a3e47a146107f8578063c2b7bbb61461059b578063c4e2c1e614610484578063d25adeb31461045d578063d7b3871314610431578063daf8497614610408578063e8673ef5146103df578063ef5cfb8c14610358578063f0f44260146102cc578063f2f4eb26146102875763fc0c546a14610240575f80fd5b346102845780600319360112610284576040517f00000000000000000000000057ab1e0003f623289cd798b1824be09a793e4bec6001600160a01b03168152602090f35b80fd5b50346102845780600319360112610284576040517f000000000000000000000000c07e000044f95655c11fda4cd37f70a94d7e0a7d6001600160a01b03168152602090f35b5034610284576020366003190112610284576103556102e96117e2565b61031d337f000000000000000000000000c07e000044f95655c11fda4cd37f70a94d7e0a7d6001600160a01b031614611bfa565b600680546001600160a01b0319166001600160a01b038316179055610340611821565b610348611821565b6020815191012091611f13565b80f35b503461028457602036600319011261028457806103736117e2565b6003546001600160a01b031690813b156103db57604051633bd73ee360e21b81526001600160a01b0390911660048201529082908290602490829084905af180156103d0576103bf5750f35b816103c99161173b565b6102845780f35b6040513d84823e3d90fd5b5050fd5b50346102845780600319360112610284576002546040516001600160a01b039091168152602090f35b50346102845780600319360112610284576008546040516001600160a01b039091168152602090f35b503461028457806003193601126102845761045961044d611ce7565b60405191829182611ad1565b0390f35b5034610284578060031936011261028457546040516001600160a01b039091168152602090f35b50346102845760603660031901126102845761049e6117e2565b6044356001600160a01b03811691602435919084848303610284576020916104f0337f000000000000000000000000c07e000044f95655c11fda4cd37f70a94d7e0a7d6001600160a01b031614611bfa565b60405163a9059cbb60e01b8482019081526001600160a01b03958616602483015260448083018890528252919094169361052b60648261173b565b519082855af1156105905783513d6105875750803b155b610575575060207f47096d7b247e809edf18e9bccfcb92f2af426ce8e6b40c923e65cb1b8394cef791604051908152a280f35b635274afe760e01b8452600452602483fd5b60011415610542565b6040513d85823e3d90fd5b5034610284576020366003190112610284576105b56117e2565b6105e9337f000000000000000000000000c07e000044f95655c11fda4cd37f70a94d7e0a7d6001600160a01b031614611bfa565b600954600160401b8110156107e4578060016106089201600955611a29565b81546001600160a01b0393841660039290921b82811b94901b19169290921790556040516306fdde0360e01b81528281600481855afa9081156105905783916107c2575b506040519080519160208201928084835e600c9082019081528190036020019020546001600160a01b03166107b357602090604051928391518091835e8101600c815203019020816bffffffffffffffffffffffff60a01b8254161790556040519082600a54918284528360208101600a84526020842094845b81811061078e5750506106dd92939450038461173b565b815b8351811015610766576001600160a01b036106fa8286611cd3565b5116823b156107625760405190633f2617cb60e01b8252600482015260016024820152838160448183875af190811561075757849161073e575b50506001016106df565b816107489161173b565b61075357825f610734565b8280fd5b6040513d86823e3d90fd5b8380fd5b507f84f21453a36d947225b71844083d0755a7939b6c09162d5ced65f7cc0ac9d42c8280a280f35b86546001600160a01b03168352600196870196899650889450602090930192016106c6565b63e99b9f6160e01b8452600484fd5b6107de91503d8085833e6107d6818361173b565b810190611b60565b5f61064c565b634e487b7160e01b83526041600452602483fd5b50346102845780600319360112610284576007546040516001600160a01b039091168152602090f35b503461028457806003193601126102845761045961083d611b30565b6040519182916020835260208301906117be565b5034610284576020366003190112610284576004359067ffffffffffffffff82116102845760206108853660048501611871565b8160405191805191829101835e600d90820190815281900382019020546040516001600160a01b039091168152f35b5034610284578060031936011261028457600b546108d181611a41565b916108df604051938461173b565b818352600b81527f0175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01db9602084015b83831061092157604051806104598782611ad1565b6001602081926109308561191b565b81520192019201919061090c565b5034610284576020366003190112610284576004359060095482101561028457602061096983611a29565b905460405160039290921b1c6001600160a01b03168152f35b503461028457806003193601126102845761045961083d611aad565b50346102845780600319360112610284576001546040516001600160a01b039091168152602090f35b50346102845780600319360112610284576004546040516001600160a01b039091168152602090f35b503461028457602036600319011261028457610355610a0d6117e2565b610a41337f000000000000000000000000c07e000044f95655c11fda4cd37f70a94d7e0a7d6001600160a01b031614611bfa565b600480546001600160a01b0319166001600160a01b038316179055610a64611a81565b610348611a81565b503461028457602036600319011261028457610355610a896117e2565b610abd337f000000000000000000000000c07e000044f95655c11fda4cd37f70a94d7e0a7d6001600160a01b031614611bfa565b600580546001600160a01b0319166001600160a01b038316179055610ae0611aad565b610348611aad565b503461028457806003193601126102845761045961083d611a81565b503461028457602036600319011261028457610355610b216117e2565b610b55337f000000000000000000000000c07e000044f95655c11fda4cd37f70a94d7e0a7d6001600160a01b031614611bfa565b600880546001600160a01b0319166001600160a01b038316179055610b78611847565b610348611847565b50346102845760403660031901126102845760043567ffffffffffffffff8111610c6857610bb2903690600401611871565b602435916001600160a01b038316830361028457610bfa337f000000000000000000000000c07e000044f95655c11fda4cd37f70a94d7e0a7d6001600160a01b031614611bfa565b8151602083012090610c0a611ce7565b90805b8251811015610c5c57610c208184611cd3565b51602081519101208414610c3657600101610c0d565b6040516316fd561360e31b81526020600482015280610c5860248201886117be565b0390fd5b50610355838587611f13565b5080fd5b503461028457806003193601126102845760035481906001600160a01b0316803b15610cb7578180916004604051809481936325f2da9160e21b83525af180156103d0576103bf5750f35b50fd5b5034610284578060031936011261028457600b5490610cd882611a41565b90610ce6604051928361173b565b828252601f19610cf584611a41565b0136602084013780925b808410610d14576040518061045985826119bb565b610d20849392936119fd565b50936040518490865496610d33886118e3565b9760018116908115610daf5750600114610d77575b5060019394959650600d8252602081858060a01b0393030190205416610d6e8286611cd3565b52019290610cff565b9091508552602085209585965b818810610d9b575094955085948101906001610d48565b600181602092548a86015201970196610d84565b60ff1916835250959687965080151502810191506001610d48565b5034610284576020366003190112610284576004359067ffffffffffffffff8211610284576020610dfe3660048501611871565b8160405191805191829101835e600c90820190815281900382019020546040516001600160a01b039091168152f35b503461028457806003193601126102845761045961083d611a59565b503461028457602036600319011261028457610355610e666117e2565b610e9a337f000000000000000000000000c07e000044f95655c11fda4cd37f70a94d7e0a7d6001600160a01b031614611bfa565b600780546001600160a01b0319166001600160a01b038316179055610ebd611a59565b610348611a59565b503461028457602036600319011261028457610355610ee26117e2565b610f16337f000000000000000000000000c07e000044f95655c11fda4cd37f70a94d7e0a7d6001600160a01b031614611bfa565b600180546001600160a01b0319166001600160a01b038316179055610f396117f8565b6103486117f8565b50346102845760203660031901126102845760043567ffffffffffffffff8111610c685736602382011215610c68578060040135610f7e81611a41565b91610f8c604051938461173b565b81835260208301906024829360051b820101903682116110ec57602401915b8183106110c85750610fea915050337f000000000000000000000000c07e000044f95655c11fda4cd37f70a94d7e0a7d6001600160a01b031614611bfa565b81519067ffffffffffffffff82116110b457600160401b82116110b457600a5482600a55808310611086575b50600a8452835b82811061105c57847f0f3c50ecdc6241494d6aacfb0c4e14d2fe9817352b949184cbff500f9f0bdf4561105686604051918291826119bb565b0390a180f35b81516001600160a01b03165f5160206120af5f395f51905f5282015560209091019060010161101d565b6110ae905f5160206120af5f395f51905f5201835f5160206120af5f395f51905f5201611c2e565b5f611016565b634e487b7160e01b84526041600452602484fd5b82356001600160a01b03811681036110e857815260209283019201610fab565b8680fd5b8580fd5b50346102845760203660031901126102845760043590600a5482101561028457600a5482101561114a57600a81525f5160206120af5f395f51905f529091015460405160039290921b1c6001600160a01b03168152602090f35b634e487b7160e01b81526032600452602490fd5b50346102845780600319360112610284576003546040516001600160a01b039091168152602090f35b50346102845780600319360112610284576006546040516001600160a01b039091168152602090f35b503461028457806003193601126102845760405160098054808352908352909160208301917f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7af915b81811061121b576104598561120f8187038261173b565b604051918291826119bb565b82546001600160a01b03168452602090930192600192830192016111f8565b50346102845780600319360112610284576005546040516001600160a01b039091168152602090f35b50346102845760203660031901126102845761083d6040610459926004358152600f6020522061191b565b503461028457806003193601126102845761045961083d6118b7565b5034610284576020366003190112610284576004359067ffffffffffffffff821161028457602060ff81806112e23660048801611871565b604051928184925191829101835e8101600e81520301902054166040519015158152f35b5034610284576020366003190112610284576103556113236117e2565b611357337f000000000000000000000000c07e000044f95655c11fda4cd37f70a94d7e0a7d6001600160a01b031614611bfa565b600280546001600160a01b0319166001600160a01b03831617905561137a611b30565b610348611b30565b503461028457806003193601126102845761045961083d611847565b5034611499576040366003190112611499576113b86117e2565b6040516306fdde0360e01b81525f81600481335afa801561148e5761140e915f9161149d575b50602060405191805191829101835e600c9082019081528190036020019020546001600160a01b03163314611bc3565b7f00000000000000000000000057ab1e0003f623289cd798b1824be09a793e4bec6001600160a01b0316803b15611499576040516340c10f1960e01b81526001600160a01b0392909216600483015260248035908301525f908290604490829084905af1801561148e57611480575080f35b61148c91505f9061173b565b005b6040513d5f823e3d90fd5b5f80fd5b6114b191503d805f833e6107d6818361173b565b5f6113de565b34611499575f3660031901126114995761045961083d611821565b34611499575f3660031901126114995761045961083d6117f8565b34611499575f366003190112611499576020600954604051908152f35b346114995760203660031901126114995761148c6115266117e2565b61155a337f000000000000000000000000c07e000044f95655c11fda4cd37f70a94d7e0a7d6001600160a01b031614611bfa565b600380546001600160a01b0319166001600160a01b03831617905561157d6118b7565b6103486118b7565b346114995760203660031901126114995761148c6115a16117e2565b6115d5337f000000000000000000000000c07e000044f95655c11fda4cd37f70a94d7e0a7d6001600160a01b031614611bfa565b5f80546001600160a01b0319166001600160a01b0383161790556115f761178d565b61034861178d565b34611499576020366003190112611499576001600160a01b036116206117e2565b166040516306fdde0360e01b81525f81600481855afa91821561148e5761167a815f9460209486916116c2575b508460405191805191829101835e600c90820190815281900385019020546001600160a01b031614611bc3565b6004604051809481936323b1a1f760e11b83525af1801561148e5761169b57005b602090813d83116116bb575b6116b1818361173b565b8101031261149957005b503d6116a7565b6116d691503d8088833e6107d6818361173b565b8661164d565b34611499575f366003190112611499576040517f000000000000000000000000419905009e4656fdc02418c7df35b1e61ed5f7266001600160a01b03168152602090f35b34611499575f3660031901126114995761045961083d61178d565b90601f8019910116810190811067ffffffffffffffff82111761175d57604052565b634e487b7160e01b5f52604160045260245ffd5b67ffffffffffffffff811161175d57601f01601f191660200190565b6040519061179c60408361173b565b60138252722624a8aaa4a220aa24a7a72fa420a7222622a960691b6020830152565b805180835260209291819084018484015e5f828201840152601f01601f1916010190565b600435906001600160a01b038216820361149957565b6040519061180760408361173b565b600b82526a11915157d1115413d4d25560aa1b6020830152565b6040519061183060408361173b565b6008825267545245415355525960c01b6020830152565b6040519061185660408361173b565b600c82526b2b22a9aa2fa6a0a720a3a2a960a11b6020830152565b81601f820112156114995780359061188882611771565b92611896604051948561173b565b8284526020838301011161149957815f926020809301838601378301015290565b604051906118c660408361173b565b600e82526d2922aba0a9222fa420a7222622a960911b6020830152565b90600182811c92168015611911575b60208310146118fd57565b634e487b7160e01b5f52602260045260245ffd5b91607f16916118f2565b9060405191825f82549261192e846118e3565b80845293600181169081156119995750600114611955575b506119539250038361173b565b565b90505f9291925260205f20905f915b81831061197d575050906020611953928201015f611946565b6020919350806001915483858901015201910190918492611964565b90506020925061195394915060ff191682840152151560051b8201015f611946565b60206040818301928281528451809452019201905f5b8181106119de5750505090565b82516001600160a01b03168452602093840193909201916001016119d1565b600b54811015611a1557600b5f5260205f2001905f90565b634e487b7160e01b5f52603260045260245ffd5b600954811015611a155760095f5260205f2001905f90565b67ffffffffffffffff811161175d5760051b60200190565b60405190611a6860408361173b565b600a82526926192fa6a0a720a3a2a960b11b6020830152565b60405190611a9060408361173b565b600e82526d125394d554905390d157d413d3d360921b6020830152565b60405190611abc60408361173b565b600682526529aa20a5a2a960d11b6020830152565b602081016020825282518091526040820191602060408360051b8301019401925f915b838310611b0357505050505090565b9091929394602080611b21600193603f1986820301875289516117be565b97019301930191939290611af4565b60405190611b3f60408361173b565b60128252712922a222a6a82a24a7a72fa420a7222622a960711b6020830152565b6020818303126114995780519067ffffffffffffffff8211611499570181601f8201121561149957805190611b9482611771565b92611ba2604051948561173b565b8284526020838301011161149957815f9260208093018386015e8301015290565b15611bca57565b60405162461bcd60e51b815260206004820152600860248201526710b932b3a830b4b960c11b6044820152606490fd5b15611c0157565b60405162461bcd60e51b815260206004820152600560248201526421636f726560d81b6044820152606490fd5b818110611c39575050565b5f8155600101611c2e565b805115611a155760200190565b805160011015611a155760400190565b805160021015611a155760600190565b805160031015611a155760800190565b805160041015611a155760a00190565b805160051015611a155760c00190565b805160061015611a155760e00190565b805160071015611a15576101000190565b805160081015611a15576101200190565b8051821015611a155760209160051b010190565b604051610140611cf7818361173b565b60098252601f19015f5b818110611e09575050611d1261178d565b611d1b82611c44565b52611d2581611c44565b50611d2e6117f8565b611d3782611c51565b52611d4181611c51565b50611d4a611b30565b611d5382611c61565b52611d5d81611c61565b50611d66611a81565b611d6f82611c71565b52611d7981611c71565b50611d826118b7565b611d8b82611c81565b52611d9581611c81565b50611d9e611821565b611da782611c91565b52611db181611c91565b50611dba611aad565b611dc382611ca1565b52611dcd81611ca1565b50611dd6611a59565b611ddf82611cb1565b52611de981611cb1565b50611df2611847565b611dfb82611cc2565b52611e0581611cc2565b5090565b806060602080938601015201611d01565b919091825167ffffffffffffffff811161175d57611e3882546118e3565b601f8111611ed8575b506020601f8211600114611e7a57819293945f92611e6f575b50508160011b915f199060031b1c1916179055565b015190505f80611e5a565b601f19821690835f52805f20915f5b818110611ec057509583600195969710611ea8575b505050811b019055565b01515f1960f88460031b161c191690555f8080611e9e565b9192602060018192868b015181550194019201611e89565b611f0390835f5260205f20601f840160051c81019160208510611f09575b601f0160051c0190611c2e565b5f611e41565b9091508190611ef6565b919091825115612073576001600160a01b0316918215612035576040519160ff825193602081818601968088835e8101600e815203019020541615611fba575b5060405160208183518086835e8101600d815203019020836bffffffffffffffffffffffff60a01b825416179055604051918291518091835e81015f81520390207f69bfa74ab5a9ec2fd819209cebf1db7f41f2fc0ce34dd9de5ffd1a8d1018b05f5f80a3565b5f52600f602052611fce8160405f20611e1a565b600b54600160401b81101561175d57806001611fed9201600b556119fd565b6120225781611ffb91611e1a565b60405160208183518086835e8101600e815203019020600160ff198254161790555f611f53565b634e487b7160e01b5f525f60045260245ffd5b60405162461bcd60e51b8152602060048201526016602482015275416464726573732063616e6e6f74206265207a65726f60501b6044820152606490fd5b60405162461bcd60e51b81526020600482015260136024820152724b65792063616e6e6f7420626520656d70747960681b6044820152606490fdfec65a7bb8d6351c1cf70c95a316cc6a92839c986682d98bc35f958f4883f9d2a8a164736f6c634300081c000a","optimization_enabled":true,"verified_twin_address_hash":null,"is_verified":true,"compiler_settings":{"evmVersion":"cancun","libraries":{},"metadata":{"bytecodeHash":"none"},"optimizer":{"enabled":true,"runs":200},"remappings":[":@axelar-network/=node_modules/@axelar-network/",":@chainlink/=node_modules/@chainlink/",":@eth-optimism/=node_modules/@eth-optimism/",":@layerzerolabs/=node_modules/@layerzerolabs/",":@mean-finance/=node_modules/@mean-finance/",":@openzeppelin/=node_modules/@openzeppelin/",":@rari-capital/=node_modules/@rari-capital/",":@uniswap/=node_modules/@uniswap/",":base64-sol/=node_modules/base64-sol/",":ds-test/=node_modules/ds-test/src/",":forge-std/=node_modules/forge-std/src/",":frax-standard-solidity/=node_modules/frax-standard-solidity/",":frax-std/=node_modules/frax-standard-solidity/src/",":hardhat-deploy/=node_modules/hardhat-deploy/",":hardhat/=node_modules/hardhat/",":solidity-bytes-utils/=node_modules/solidity-bytes-utils/",":solidity-stringutils/=lib/surl/lib/solidity-stringutils/",":surl/=lib/surl/"],"viaIR":true},"optimization_runs":200,"sourcify_repo_url":"https://repo.sourcify.dev/contracts/partial_match/1/0x10101010E0C3171D894B71B3400668aF311e7D94/","decoded_constructor_args":[["0xc07e000044F95655c11fda4cD37F70A94d7e0a7d",{"internalType":"address","name":"_core","type":"address"}],["0x57aB1E0003F623289CD798B1824Be09a793e4Bec",{"internalType":"address","name":"_token","type":"address"}],["0x419905009e4656fdC02418C7Df35B1E61Ed5F726",{"internalType":"address","name":"_govToken","type":"address"}]],"compiler_version":"0.8.28+commit.7893614a","is_verified_via_verifier_alliance":false,"verified_at":"2025-05-27T19:54:55.746499Z","implementations":[],"proxy_type":null,"external_libraries":[],"creation_bytecode":"0x60e03461010057601f61220838819003918201601f19168301916001600160401b03831184841017610104578084926060946040528339810103126101005761004781610118565b90610060604061005960208401610118565b9201610118565b6001600160a01b0390921660805260a05260c0526040516120db908161012d823960805181818161029d015281816102ef015281816104c2015281816105bb01528181610a1301528181610a8f01528181610b2701528181610bcc01528181610e6c01528181610ee801528181610fbc015281816113290152818161152c01526115a7015260a0518181816102550152611410015260c051816116f10152f35b5f80fd5b634e487b7160e01b5f52604160045260245ffd5b51906001600160a01b03821682036101005756fe60806040526004361015610011575f80fd5b5f5f3560e01c806302be459e1461172057806305268cff146116dc57806315a0ea6a146115ff57806316510108146115855780631deee6121461150a57806323103b7d146114ed57806326e53399146114d25780632d2c5565146114b757806340c10f191461139e57806345c881a01461138257806357e3e8d31461130657806358537ca9146112aa5780635baffe8e1461128e5780635cdcfadf146112635780635ebaf1db1461123a578063607b6d16146111b057806361d027b314611187578063670fb8211461115e57806369285727146110f05780636c191eee14610f415780637a883d6e14610ec557806382aa4e0614610e495780638387832514610e2d5780638413aec714610dca5780638da5cb5b146102875780639516a10414610cba57806397cb6a4414610c6c5780639b2ea4bd14610b805780639efc920814610b04578063a13aed1f14610ae8578063a29a43bb14610a6c578063a94c487e146109f0578063ab2adc00146109c7578063abca72901461099e578063b0df4cab14610982578063b1fc70081461093e578063bc87eed3146108b4578063bf40fac114610851578063bff59f8f14610821578063c1a3e47a146107f8578063c2b7bbb61461059b578063c4e2c1e614610484578063d25adeb31461045d578063d7b3871314610431578063daf8497614610408578063e8673ef5146103df578063ef5cfb8c14610358578063f0f44260146102cc578063f2f4eb26146102875763fc0c546a14610240575f80fd5b346102845780600319360112610284576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b80fd5b50346102845780600319360112610284576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b5034610284576020366003190112610284576103556102e96117e2565b61031d337f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031614611bfa565b600680546001600160a01b0319166001600160a01b038316179055610340611821565b610348611821565b6020815191012091611f13565b80f35b503461028457602036600319011261028457806103736117e2565b6003546001600160a01b031690813b156103db57604051633bd73ee360e21b81526001600160a01b0390911660048201529082908290602490829084905af180156103d0576103bf5750f35b816103c99161173b565b6102845780f35b6040513d84823e3d90fd5b5050fd5b50346102845780600319360112610284576002546040516001600160a01b039091168152602090f35b50346102845780600319360112610284576008546040516001600160a01b039091168152602090f35b503461028457806003193601126102845761045961044d611ce7565b60405191829182611ad1565b0390f35b5034610284578060031936011261028457546040516001600160a01b039091168152602090f35b50346102845760603660031901126102845761049e6117e2565b6044356001600160a01b03811691602435919084848303610284576020916104f0337f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031614611bfa565b60405163a9059cbb60e01b8482019081526001600160a01b03958616602483015260448083018890528252919094169361052b60648261173b565b519082855af1156105905783513d6105875750803b155b610575575060207f47096d7b247e809edf18e9bccfcb92f2af426ce8e6b40c923e65cb1b8394cef791604051908152a280f35b635274afe760e01b8452600452602483fd5b60011415610542565b6040513d85823e3d90fd5b5034610284576020366003190112610284576105b56117e2565b6105e9337f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031614611bfa565b600954600160401b8110156107e4578060016106089201600955611a29565b81546001600160a01b0393841660039290921b82811b94901b19169290921790556040516306fdde0360e01b81528281600481855afa9081156105905783916107c2575b506040519080519160208201928084835e600c9082019081528190036020019020546001600160a01b03166107b357602090604051928391518091835e8101600c815203019020816bffffffffffffffffffffffff60a01b8254161790556040519082600a54918284528360208101600a84526020842094845b81811061078e5750506106dd92939450038461173b565b815b8351811015610766576001600160a01b036106fa8286611cd3565b5116823b156107625760405190633f2617cb60e01b8252600482015260016024820152838160448183875af190811561075757849161073e575b50506001016106df565b816107489161173b565b61075357825f610734565b8280fd5b6040513d86823e3d90fd5b8380fd5b507f84f21453a36d947225b71844083d0755a7939b6c09162d5ced65f7cc0ac9d42c8280a280f35b86546001600160a01b03168352600196870196899650889450602090930192016106c6565b63e99b9f6160e01b8452600484fd5b6107de91503d8085833e6107d6818361173b565b810190611b60565b5f61064c565b634e487b7160e01b83526041600452602483fd5b50346102845780600319360112610284576007546040516001600160a01b039091168152602090f35b503461028457806003193601126102845761045961083d611b30565b6040519182916020835260208301906117be565b5034610284576020366003190112610284576004359067ffffffffffffffff82116102845760206108853660048501611871565b8160405191805191829101835e600d90820190815281900382019020546040516001600160a01b039091168152f35b5034610284578060031936011261028457600b546108d181611a41565b916108df604051938461173b565b818352600b81527f0175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01db9602084015b83831061092157604051806104598782611ad1565b6001602081926109308561191b565b81520192019201919061090c565b5034610284576020366003190112610284576004359060095482101561028457602061096983611a29565b905460405160039290921b1c6001600160a01b03168152f35b503461028457806003193601126102845761045961083d611aad565b50346102845780600319360112610284576001546040516001600160a01b039091168152602090f35b50346102845780600319360112610284576004546040516001600160a01b039091168152602090f35b503461028457602036600319011261028457610355610a0d6117e2565b610a41337f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031614611bfa565b600480546001600160a01b0319166001600160a01b038316179055610a64611a81565b610348611a81565b503461028457602036600319011261028457610355610a896117e2565b610abd337f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031614611bfa565b600580546001600160a01b0319166001600160a01b038316179055610ae0611aad565b610348611aad565b503461028457806003193601126102845761045961083d611a81565b503461028457602036600319011261028457610355610b216117e2565b610b55337f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031614611bfa565b600880546001600160a01b0319166001600160a01b038316179055610b78611847565b610348611847565b50346102845760403660031901126102845760043567ffffffffffffffff8111610c6857610bb2903690600401611871565b602435916001600160a01b038316830361028457610bfa337f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031614611bfa565b8151602083012090610c0a611ce7565b90805b8251811015610c5c57610c208184611cd3565b51602081519101208414610c3657600101610c0d565b6040516316fd561360e31b81526020600482015280610c5860248201886117be565b0390fd5b50610355838587611f13565b5080fd5b503461028457806003193601126102845760035481906001600160a01b0316803b15610cb7578180916004604051809481936325f2da9160e21b83525af180156103d0576103bf5750f35b50fd5b5034610284578060031936011261028457600b5490610cd882611a41565b90610ce6604051928361173b565b828252601f19610cf584611a41565b0136602084013780925b808410610d14576040518061045985826119bb565b610d20849392936119fd565b50936040518490865496610d33886118e3565b9760018116908115610daf5750600114610d77575b5060019394959650600d8252602081858060a01b0393030190205416610d6e8286611cd3565b52019290610cff565b9091508552602085209585965b818810610d9b575094955085948101906001610d48565b600181602092548a86015201970196610d84565b60ff1916835250959687965080151502810191506001610d48565b5034610284576020366003190112610284576004359067ffffffffffffffff8211610284576020610dfe3660048501611871565b8160405191805191829101835e600c90820190815281900382019020546040516001600160a01b039091168152f35b503461028457806003193601126102845761045961083d611a59565b503461028457602036600319011261028457610355610e666117e2565b610e9a337f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031614611bfa565b600780546001600160a01b0319166001600160a01b038316179055610ebd611a59565b610348611a59565b503461028457602036600319011261028457610355610ee26117e2565b610f16337f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031614611bfa565b600180546001600160a01b0319166001600160a01b038316179055610f396117f8565b6103486117f8565b50346102845760203660031901126102845760043567ffffffffffffffff8111610c685736602382011215610c68578060040135610f7e81611a41565b91610f8c604051938461173b565b81835260208301906024829360051b820101903682116110ec57602401915b8183106110c85750610fea915050337f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031614611bfa565b81519067ffffffffffffffff82116110b457600160401b82116110b457600a5482600a55808310611086575b50600a8452835b82811061105c57847f0f3c50ecdc6241494d6aacfb0c4e14d2fe9817352b949184cbff500f9f0bdf4561105686604051918291826119bb565b0390a180f35b81516001600160a01b03165f5160206120af5f395f51905f5282015560209091019060010161101d565b6110ae905f5160206120af5f395f51905f5201835f5160206120af5f395f51905f5201611c2e565b5f611016565b634e487b7160e01b84526041600452602484fd5b82356001600160a01b03811681036110e857815260209283019201610fab565b8680fd5b8580fd5b50346102845760203660031901126102845760043590600a5482101561028457600a5482101561114a57600a81525f5160206120af5f395f51905f529091015460405160039290921b1c6001600160a01b03168152602090f35b634e487b7160e01b81526032600452602490fd5b50346102845780600319360112610284576003546040516001600160a01b039091168152602090f35b50346102845780600319360112610284576006546040516001600160a01b039091168152602090f35b503461028457806003193601126102845760405160098054808352908352909160208301917f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7af915b81811061121b576104598561120f8187038261173b565b604051918291826119bb565b82546001600160a01b03168452602090930192600192830192016111f8565b50346102845780600319360112610284576005546040516001600160a01b039091168152602090f35b50346102845760203660031901126102845761083d6040610459926004358152600f6020522061191b565b503461028457806003193601126102845761045961083d6118b7565b5034610284576020366003190112610284576004359067ffffffffffffffff821161028457602060ff81806112e23660048801611871565b604051928184925191829101835e8101600e81520301902054166040519015158152f35b5034610284576020366003190112610284576103556113236117e2565b611357337f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031614611bfa565b600280546001600160a01b0319166001600160a01b03831617905561137a611b30565b610348611b30565b503461028457806003193601126102845761045961083d611847565b5034611499576040366003190112611499576113b86117e2565b6040516306fdde0360e01b81525f81600481335afa801561148e5761140e915f9161149d575b50602060405191805191829101835e600c9082019081528190036020019020546001600160a01b03163314611bc3565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316803b15611499576040516340c10f1960e01b81526001600160a01b0392909216600483015260248035908301525f908290604490829084905af1801561148e57611480575080f35b61148c91505f9061173b565b005b6040513d5f823e3d90fd5b5f80fd5b6114b191503d805f833e6107d6818361173b565b5f6113de565b34611499575f3660031901126114995761045961083d611821565b34611499575f3660031901126114995761045961083d6117f8565b34611499575f366003190112611499576020600954604051908152f35b346114995760203660031901126114995761148c6115266117e2565b61155a337f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031614611bfa565b600380546001600160a01b0319166001600160a01b03831617905561157d6118b7565b6103486118b7565b346114995760203660031901126114995761148c6115a16117e2565b6115d5337f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031614611bfa565b5f80546001600160a01b0319166001600160a01b0383161790556115f761178d565b61034861178d565b34611499576020366003190112611499576001600160a01b036116206117e2565b166040516306fdde0360e01b81525f81600481855afa91821561148e5761167a815f9460209486916116c2575b508460405191805191829101835e600c90820190815281900385019020546001600160a01b031614611bc3565b6004604051809481936323b1a1f760e11b83525af1801561148e5761169b57005b602090813d83116116bb575b6116b1818361173b565b8101031261149957005b503d6116a7565b6116d691503d8088833e6107d6818361173b565b8661164d565b34611499575f366003190112611499576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b34611499575f3660031901126114995761045961083d61178d565b90601f8019910116810190811067ffffffffffffffff82111761175d57604052565b634e487b7160e01b5f52604160045260245ffd5b67ffffffffffffffff811161175d57601f01601f191660200190565b6040519061179c60408361173b565b60138252722624a8aaa4a220aa24a7a72fa420a7222622a960691b6020830152565b805180835260209291819084018484015e5f828201840152601f01601f1916010190565b600435906001600160a01b038216820361149957565b6040519061180760408361173b565b600b82526a11915157d1115413d4d25560aa1b6020830152565b6040519061183060408361173b565b6008825267545245415355525960c01b6020830152565b6040519061185660408361173b565b600c82526b2b22a9aa2fa6a0a720a3a2a960a11b6020830152565b81601f820112156114995780359061188882611771565b92611896604051948561173b565b8284526020838301011161149957815f926020809301838601378301015290565b604051906118c660408361173b565b600e82526d2922aba0a9222fa420a7222622a960911b6020830152565b90600182811c92168015611911575b60208310146118fd57565b634e487b7160e01b5f52602260045260245ffd5b91607f16916118f2565b9060405191825f82549261192e846118e3565b80845293600181169081156119995750600114611955575b506119539250038361173b565b565b90505f9291925260205f20905f915b81831061197d575050906020611953928201015f611946565b6020919350806001915483858901015201910190918492611964565b90506020925061195394915060ff191682840152151560051b8201015f611946565b60206040818301928281528451809452019201905f5b8181106119de5750505090565b82516001600160a01b03168452602093840193909201916001016119d1565b600b54811015611a1557600b5f5260205f2001905f90565b634e487b7160e01b5f52603260045260245ffd5b600954811015611a155760095f5260205f2001905f90565b67ffffffffffffffff811161175d5760051b60200190565b60405190611a6860408361173b565b600a82526926192fa6a0a720a3a2a960b11b6020830152565b60405190611a9060408361173b565b600e82526d125394d554905390d157d413d3d360921b6020830152565b60405190611abc60408361173b565b600682526529aa20a5a2a960d11b6020830152565b602081016020825282518091526040820191602060408360051b8301019401925f915b838310611b0357505050505090565b9091929394602080611b21600193603f1986820301875289516117be565b97019301930191939290611af4565b60405190611b3f60408361173b565b60128252712922a222a6a82a24a7a72fa420a7222622a960711b6020830152565b6020818303126114995780519067ffffffffffffffff8211611499570181601f8201121561149957805190611b9482611771565b92611ba2604051948561173b565b8284526020838301011161149957815f9260208093018386015e8301015290565b15611bca57565b60405162461bcd60e51b815260206004820152600860248201526710b932b3a830b4b960c11b6044820152606490fd5b15611c0157565b60405162461bcd60e51b815260206004820152600560248201526421636f726560d81b6044820152606490fd5b818110611c39575050565b5f8155600101611c2e565b805115611a155760200190565b805160011015611a155760400190565b805160021015611a155760600190565b805160031015611a155760800190565b805160041015611a155760a00190565b805160051015611a155760c00190565b805160061015611a155760e00190565b805160071015611a15576101000190565b805160081015611a15576101200190565b8051821015611a155760209160051b010190565b604051610140611cf7818361173b565b60098252601f19015f5b818110611e09575050611d1261178d565b611d1b82611c44565b52611d2581611c44565b50611d2e6117f8565b611d3782611c51565b52611d4181611c51565b50611d4a611b30565b611d5382611c61565b52611d5d81611c61565b50611d66611a81565b611d6f82611c71565b52611d7981611c71565b50611d826118b7565b611d8b82611c81565b52611d9581611c81565b50611d9e611821565b611da782611c91565b52611db181611c91565b50611dba611aad565b611dc382611ca1565b52611dcd81611ca1565b50611dd6611a59565b611ddf82611cb1565b52611de981611cb1565b50611df2611847565b611dfb82611cc2565b52611e0581611cc2565b5090565b806060602080938601015201611d01565b919091825167ffffffffffffffff811161175d57611e3882546118e3565b601f8111611ed8575b506020601f8211600114611e7a57819293945f92611e6f575b50508160011b915f199060031b1c1916179055565b015190505f80611e5a565b601f19821690835f52805f20915f5b818110611ec057509583600195969710611ea8575b505050811b019055565b01515f1960f88460031b161c191690555f8080611e9e565b9192602060018192868b015181550194019201611e89565b611f0390835f5260205f20601f840160051c81019160208510611f09575b601f0160051c0190611c2e565b5f611e41565b9091508190611ef6565b919091825115612073576001600160a01b0316918215612035576040519160ff825193602081818601968088835e8101600e815203019020541615611fba575b5060405160208183518086835e8101600d815203019020836bffffffffffffffffffffffff60a01b825416179055604051918291518091835e81015f81520390207f69bfa74ab5a9ec2fd819209cebf1db7f41f2fc0ce34dd9de5ffd1a8d1018b05f5f80a3565b5f52600f602052611fce8160405f20611e1a565b600b54600160401b81101561175d57806001611fed9201600b556119fd565b6120225781611ffb91611e1a565b60405160208183518086835e8101600e815203019020600160ff198254161790555f611f53565b634e487b7160e01b5f525f60045260245ffd5b60405162461bcd60e51b8152602060048201526016602482015275416464726573732063616e6e6f74206265207a65726f60501b6044820152606490fd5b60405162461bcd60e51b81526020600482015260136024820152724b65792063616e6e6f7420626520656d70747960681b6044820152606490fdfec65a7bb8d6351c1cf70c95a316cc6a92839c986682d98bc35f958f4883f9d2a8a164736f6c634300081c000a000000000000000000000000c07e000044f95655c11fda4cd37f70a94d7e0a7d00000000000000000000000057ab1e0003f623289cd798b1824be09a793e4bec000000000000000000000000419905009e4656fdc02418c7df35b1e61ed5f726","name":"ResupplyRegistry","is_blueprint":false,"license_type":"none","is_fully_verified":false,"is_verified_via_eth_bytecode_db":true,"language":"solidity","evm_version":"cancun","can_be_visualized_via_sol2uml":true,"is_verified_via_sourcify":true,"additional_sources":[{"file_path":"node_modules/@openzeppelin/contracts/interfaces/IERC1363.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (interfaces/IERC1363.sol)\n\npragma solidity ^0.8.20;\n\nimport {IERC20} from \"./IERC20.sol\";\nimport {IERC165} from \"./IERC165.sol\";\n\n/**\n * @title IERC1363\n * @dev Interface of the ERC-1363 standard as defined in the https://eips.ethereum.org/EIPS/eip-1363[ERC-1363].\n *\n * Defines an extension interface for ERC-20 tokens that supports executing code on a recipient contract\n * after `transfer` or `transferFrom`, or code on a spender contract after `approve`, in a single transaction.\n */\ninterface IERC1363 is IERC20, IERC165 {\n    /*\n     * Note: the ERC-165 identifier for this interface is 0xb0202a11.\n     * 0xb0202a11 ===\n     *   bytes4(keccak256('transferAndCall(address,uint256)')) ^\n     *   bytes4(keccak256('transferAndCall(address,uint256,bytes)')) ^\n     *   bytes4(keccak256('transferFromAndCall(address,address,uint256)')) ^\n     *   bytes4(keccak256('transferFromAndCall(address,address,uint256,bytes)')) ^\n     *   bytes4(keccak256('approveAndCall(address,uint256)')) ^\n     *   bytes4(keccak256('approveAndCall(address,uint256,bytes)'))\n     */\n\n    /**\n     * @dev Moves a `value` amount of tokens from the caller's account to `to`\n     * and then calls {IERC1363Receiver-onTransferReceived} on `to`.\n     * @param to The address which you want to transfer to.\n     * @param value The amount of tokens to be transferred.\n     * @return A boolean value indicating whether the operation succeeded unless throwing.\n     */\n    function transferAndCall(address to, uint256 value) external returns (bool);\n\n    /**\n     * @dev Moves a `value` amount of tokens from the caller's account to `to`\n     * and then calls {IERC1363Receiver-onTransferReceived} on `to`.\n     * @param to The address which you want to transfer to.\n     * @param value The amount of tokens to be transferred.\n     * @param data Additional data with no specified format, sent in call to `to`.\n     * @return A boolean value indicating whether the operation succeeded unless throwing.\n     */\n    function transferAndCall(address to, uint256 value, bytes calldata data) external returns (bool);\n\n    /**\n     * @dev Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism\n     * and then calls {IERC1363Receiver-onTransferReceived} on `to`.\n     * @param from The address which you want to send tokens from.\n     * @param to The address which you want to transfer to.\n     * @param value The amount of tokens to be transferred.\n     * @return A boolean value indicating whether the operation succeeded unless throwing.\n     */\n    function transferFromAndCall(address from, address to, uint256 value) external returns (bool);\n\n    /**\n     * @dev Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism\n     * and then calls {IERC1363Receiver-onTransferReceived} on `to`.\n     * @param from The address which you want to send tokens from.\n     * @param to The address which you want to transfer to.\n     * @param value The amount of tokens to be transferred.\n     * @param data Additional data with no specified format, sent in call to `to`.\n     * @return A boolean value indicating whether the operation succeeded unless throwing.\n     */\n    function transferFromAndCall(address from, address to, uint256 value, bytes calldata data) external returns (bool);\n\n    /**\n     * @dev Sets a `value` amount of tokens as the allowance of `spender` over the\n     * caller's tokens and then calls {IERC1363Spender-onApprovalReceived} on `spender`.\n     * @param spender The address which will spend the funds.\n     * @param value The amount of tokens to be spent.\n     * @return A boolean value indicating whether the operation succeeded unless throwing.\n     */\n    function approveAndCall(address spender, uint256 value) external returns (bool);\n\n    /**\n     * @dev Sets a `value` amount of tokens as the allowance of `spender` over the\n     * caller's tokens and then calls {IERC1363Spender-onApprovalReceived} on `spender`.\n     * @param spender The address which will spend the funds.\n     * @param value The amount of tokens to be spent.\n     * @param data Additional data with no specified format, sent in call to `spender`.\n     * @return A boolean value indicating whether the operation succeeded unless throwing.\n     */\n    function approveAndCall(address spender, uint256 value, bytes calldata data) external returns (bool);\n}\n"},{"file_path":"node_modules/@openzeppelin/contracts/interfaces/IERC165.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC165.sol)\n\npragma solidity ^0.8.20;\n\nimport {IERC165} from \"../utils/introspection/IERC165.sol\";\n"},{"file_path":"node_modules/@openzeppelin/contracts/interfaces/IERC20.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC20.sol)\n\npragma solidity ^0.8.20;\n\nimport {IERC20} from \"../token/ERC20/IERC20.sol\";\n"},{"file_path":"node_modules/@openzeppelin/contracts/token/ERC20/IERC20.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Interface of the ERC-20 standard as defined in the ERC.\n */\ninterface IERC20 {\n    /**\n     * @dev Emitted when `value` tokens are moved from one account (`from`) to\n     * another (`to`).\n     *\n     * Note that `value` may be zero.\n     */\n    event Transfer(address indexed from, address indexed to, uint256 value);\n\n    /**\n     * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n     * a call to {approve}. `value` is the new allowance.\n     */\n    event Approval(address indexed owner, address indexed spender, uint256 value);\n\n    /**\n     * @dev Returns the value of tokens in existence.\n     */\n    function totalSupply() external view returns (uint256);\n\n    /**\n     * @dev Returns the value of tokens owned by `account`.\n     */\n    function balanceOf(address account) external view returns (uint256);\n\n    /**\n     * @dev Moves a `value` amount of tokens from the caller's account to `to`.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transfer(address to, uint256 value) external returns (bool);\n\n    /**\n     * @dev Returns the remaining number of tokens that `spender` will be\n     * allowed to spend on behalf of `owner` through {transferFrom}. This is\n     * zero by default.\n     *\n     * This value changes when {approve} or {transferFrom} are called.\n     */\n    function allowance(address owner, address spender) external view returns (uint256);\n\n    /**\n     * @dev Sets a `value` amount of tokens as the allowance of `spender` over the\n     * caller's tokens.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * IMPORTANT: Beware that changing an allowance with this method brings the risk\n     * that someone may use both the old and the new allowance by unfortunate\n     * transaction ordering. One possible solution to mitigate this race\n     * condition is to first reduce the spender's allowance to 0 and set the\n     * desired value afterwards:\n     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n     *\n     * Emits an {Approval} event.\n     */\n    function approve(address spender, uint256 value) external returns (bool);\n\n    /**\n     * @dev Moves a `value` amount of tokens from `from` to `to` using the\n     * allowance mechanism. `value` is then deducted from the caller's\n     * allowance.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transferFrom(address from, address to, uint256 value) external returns (bool);\n}\n"},{"file_path":"node_modules/@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.20;\n\nimport {IERC20} from \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC-20 standard.\n */\ninterface IERC20Metadata is IERC20 {\n    /**\n     * @dev Returns the name of the token.\n     */\n    function name() external view returns (string memory);\n\n    /**\n     * @dev Returns the symbol of the token.\n     */\n    function symbol() external view returns (string memory);\n\n    /**\n     * @dev Returns the decimals places of the token.\n     */\n    function decimals() external view returns (uint8);\n}\n"},{"file_path":"node_modules/@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.20;\n\nimport {IERC20} from \"../IERC20.sol\";\nimport {IERC1363} from \"../../../interfaces/IERC1363.sol\";\nimport {Address} from \"../../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC-20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n    /**\n     * @dev An operation with an ERC-20 token failed.\n     */\n    error SafeERC20FailedOperation(address token);\n\n    /**\n     * @dev Indicates a failed `decreaseAllowance` request.\n     */\n    error SafeERC20FailedDecreaseAllowance(address spender, uint256 currentAllowance, uint256 requestedDecrease);\n\n    /**\n     * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\n     * non-reverting calls are assumed to be successful.\n     */\n    function safeTransfer(IERC20 token, address to, uint256 value) internal {\n        _callOptionalReturn(token, abi.encodeCall(token.transfer, (to, value)));\n    }\n\n    /**\n     * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\n     * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\n     */\n    function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\n        _callOptionalReturn(token, abi.encodeCall(token.transferFrom, (from, to, value)));\n    }\n\n    /**\n     * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\n     * non-reverting calls are assumed to be successful.\n     *\n     * IMPORTANT: If the token implements ERC-7674 (ERC-20 with temporary allowance), and if the \"client\"\n     * smart contract uses ERC-7674 to set temporary allowances, then the \"client\" smart contract should avoid using\n     * this function. Performing a {safeIncreaseAllowance} or {safeDecreaseAllowance} operation on a token contract\n     * that has a non-zero temporary allowance (for that particular owner-spender) will result in unexpected behavior.\n     */\n    function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n        uint256 oldAllowance = token.allowance(address(this), spender);\n        forceApprove(token, spender, oldAllowance + value);\n    }\n\n    /**\n     * @dev Decrease the calling contract's allowance toward `spender` by `requestedDecrease`. If `token` returns no\n     * value, non-reverting calls are assumed to be successful.\n     *\n     * IMPORTANT: If the token implements ERC-7674 (ERC-20 with temporary allowance), and if the \"client\"\n     * smart contract uses ERC-7674 to set temporary allowances, then the \"client\" smart contract should avoid using\n     * this function. Performing a {safeIncreaseAllowance} or {safeDecreaseAllowance} operation on a token contract\n     * that has a non-zero temporary allowance (for that particular owner-spender) will result in unexpected behavior.\n     */\n    function safeDecreaseAllowance(IERC20 token, address spender, uint256 requestedDecrease) internal {\n        unchecked {\n            uint256 currentAllowance = token.allowance(address(this), spender);\n            if (currentAllowance < requestedDecrease) {\n                revert SafeERC20FailedDecreaseAllowance(spender, currentAllowance, requestedDecrease);\n            }\n            forceApprove(token, spender, currentAllowance - requestedDecrease);\n        }\n    }\n\n    /**\n     * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\n     * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval\n     * to be set to zero before setting it to a non-zero value, such as USDT.\n     *\n     * NOTE: If the token implements ERC-7674, this function will not modify any temporary allowance. This function\n     * only sets the \"standard\" allowance. Any temporary allowance will remain active, in addition to the value being\n     * set here.\n     */\n    function forceApprove(IERC20 token, address spender, uint256 value) internal {\n        bytes memory approvalCall = abi.encodeCall(token.approve, (spender, value));\n\n        if (!_callOptionalReturnBool(token, approvalCall)) {\n            _callOptionalReturn(token, abi.encodeCall(token.approve, (spender, 0)));\n            _callOptionalReturn(token, approvalCall);\n        }\n    }\n\n    /**\n     * @dev Performs an {ERC1363} transferAndCall, with a fallback to the simple {ERC20} transfer if the target has no\n     * code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when\n     * targeting contracts.\n     *\n     * Reverts if the returned value is other than `true`.\n     */\n    function transferAndCallRelaxed(IERC1363 token, address to, uint256 value, bytes memory data) internal {\n        if (to.code.length == 0) {\n            safeTransfer(token, to, value);\n        } else if (!token.transferAndCall(to, value, data)) {\n            revert SafeERC20FailedOperation(address(token));\n        }\n    }\n\n    /**\n     * @dev Performs an {ERC1363} transferFromAndCall, with a fallback to the simple {ERC20} transferFrom if the target\n     * has no code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when\n     * targeting contracts.\n     *\n     * Reverts if the returned value is other than `true`.\n     */\n    function transferFromAndCallRelaxed(\n        IERC1363 token,\n        address from,\n        address to,\n        uint256 value,\n        bytes memory data\n    ) internal {\n        if (to.code.length == 0) {\n            safeTransferFrom(token, from, to, value);\n        } else if (!token.transferFromAndCall(from, to, value, data)) {\n            revert SafeERC20FailedOperation(address(token));\n        }\n    }\n\n    /**\n     * @dev Performs an {ERC1363} approveAndCall, with a fallback to the simple {ERC20} approve if the target has no\n     * code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when\n     * targeting contracts.\n     *\n     * NOTE: When the recipient address (`to`) has no code (i.e. is an EOA), this function behaves as {forceApprove}.\n     * Opposedly, when the recipient address (`to`) has code, this function only attempts to call {ERC1363-approveAndCall}\n     * once without retrying, and relies on the returned value to be true.\n     *\n     * Reverts if the returned value is other than `true`.\n     */\n    function approveAndCallRelaxed(IERC1363 token, address to, uint256 value, bytes memory data) internal {\n        if (to.code.length == 0) {\n            forceApprove(token, to, value);\n        } else if (!token.approveAndCall(to, value, data)) {\n            revert SafeERC20FailedOperation(address(token));\n        }\n    }\n\n    /**\n     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n     * on the return value: the return value is optional (but if data is returned, it must not be false).\n     * @param token The token targeted by the call.\n     * @param data The call data (encoded using abi.encode or one of its variants).\n     *\n     * This is a variant of {_callOptionalReturnBool} that reverts if call fails to meet the requirements.\n     */\n    function _callOptionalReturn(IERC20 token, bytes memory data) private {\n        uint256 returnSize;\n        uint256 returnValue;\n        assembly (\"memory-safe\") {\n            let success := call(gas(), token, 0, add(data, 0x20), mload(data), 0, 0x20)\n            // bubble errors\n            if iszero(success) {\n                let ptr := mload(0x40)\n                returndatacopy(ptr, 0, returndatasize())\n                revert(ptr, returndatasize())\n            }\n            returnSize := returndatasize()\n            returnValue := mload(0)\n        }\n\n        if (returnSize == 0 ? address(token).code.length == 0 : returnValue != 1) {\n            revert SafeERC20FailedOperation(address(token));\n        }\n    }\n\n    /**\n     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n     * on the return value: the return value is optional (but if data is returned, it must not be false).\n     * @param token The token targeted by the call.\n     * @param data The call data (encoded using abi.encode or one of its variants).\n     *\n     * This is a variant of {_callOptionalReturn} that silently catches all reverts and returns a bool instead.\n     */\n    function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {\n        bool success;\n        uint256 returnSize;\n        uint256 returnValue;\n        assembly (\"memory-safe\") {\n            success := call(gas(), token, 0, add(data, 0x20), mload(data), 0, 0x20)\n            returnSize := returndatasize()\n            returnValue := mload(0)\n        }\n        return success && (returnSize == 0 ? address(token).code.length > 0 : returnValue == 1);\n    }\n}\n"},{"file_path":"node_modules/@openzeppelin/contracts/utils/Address.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (utils/Address.sol)\n\npragma solidity ^0.8.20;\n\nimport {Errors} from \"./Errors.sol\";\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n    /**\n     * @dev There's no code at `target` (it is not a contract).\n     */\n    error AddressEmptyCode(address target);\n\n    /**\n     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n     * `recipient`, forwarding all available gas and reverting on errors.\n     *\n     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n     * of certain opcodes, possibly making contracts go over the 2300 gas limit\n     * imposed by `transfer`, making them unable to receive funds via\n     * `transfer`. {sendValue} removes this limitation.\n     *\n     * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n     *\n     * IMPORTANT: because control is transferred to `recipient`, care must be\n     * taken to not create reentrancy vulnerabilities. Consider using\n     * {ReentrancyGuard} or the\n     * https://solidity.readthedocs.io/en/v0.8.20/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n     */\n    function sendValue(address payable recipient, uint256 amount) internal {\n        if (address(this).balance < amount) {\n            revert Errors.InsufficientBalance(address(this).balance, amount);\n        }\n\n        (bool success, ) = recipient.call{value: amount}(\"\");\n        if (!success) {\n            revert Errors.FailedCall();\n        }\n    }\n\n    /**\n     * @dev Performs a Solidity function call using a low level `call`. A\n     * plain `call` is an unsafe replacement for a function call: use this\n     * function instead.\n     *\n     * If `target` reverts with a revert reason or custom error, it is bubbled\n     * up by this function (like regular Solidity function calls). However, if\n     * the call reverted with no returned reason, this function reverts with a\n     * {Errors.FailedCall} error.\n     *\n     * Returns the raw returned data. To convert to the expected return value,\n     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n     *\n     * Requirements:\n     *\n     * - `target` must be a contract.\n     * - calling `target` with `data` must not revert.\n     */\n    function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, 0);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but also transferring `value` wei to `target`.\n     *\n     * Requirements:\n     *\n     * - the calling contract must have an ETH balance of at least `value`.\n     * - the called Solidity function must be `payable`.\n     */\n    function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n        if (address(this).balance < value) {\n            revert Errors.InsufficientBalance(address(this).balance, value);\n        }\n        (bool success, bytes memory returndata) = target.call{value: value}(data);\n        return verifyCallResultFromTarget(target, success, returndata);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but performing a static call.\n     */\n    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n        (bool success, bytes memory returndata) = target.staticcall(data);\n        return verifyCallResultFromTarget(target, success, returndata);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but performing a delegate call.\n     */\n    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n        (bool success, bytes memory returndata) = target.delegatecall(data);\n        return verifyCallResultFromTarget(target, success, returndata);\n    }\n\n    /**\n     * @dev Tool to verify that a low level call to smart-contract was successful, and reverts if the target\n     * was not a contract or bubbling up the revert reason (falling back to {Errors.FailedCall}) in case\n     * of an unsuccessful call.\n     */\n    function verifyCallResultFromTarget(\n        address target,\n        bool success,\n        bytes memory returndata\n    ) internal view returns (bytes memory) {\n        if (!success) {\n            _revert(returndata);\n        } else {\n            // only check if target is a contract if the call was successful and the return data is empty\n            // otherwise we already know that it was a contract\n            if (returndata.length == 0 && target.code.length == 0) {\n                revert AddressEmptyCode(target);\n            }\n            return returndata;\n        }\n    }\n\n    /**\n     * @dev Tool to verify that a low level call was successful, and reverts if it wasn't, either by bubbling the\n     * revert reason or with a default {Errors.FailedCall} error.\n     */\n    function verifyCallResult(bool success, bytes memory returndata) internal pure returns (bytes memory) {\n        if (!success) {\n            _revert(returndata);\n        } else {\n            return returndata;\n        }\n    }\n\n    /**\n     * @dev Reverts with returndata if present. Otherwise reverts with {Errors.FailedCall}.\n     */\n    function _revert(bytes memory returndata) private pure {\n        // Look for revert reason and bubble it up if present\n        if (returndata.length > 0) {\n            // The easiest way to bubble the revert reason is using memory via assembly\n            assembly (\"memory-safe\") {\n                let returndata_size := mload(returndata)\n                revert(add(32, returndata), returndata_size)\n            }\n        } else {\n            revert Errors.FailedCall();\n        }\n    }\n}\n"},{"file_path":"node_modules/@openzeppelin/contracts/utils/Errors.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (utils/Errors.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Collection of common custom errors used in multiple contracts\n *\n * IMPORTANT: Backwards compatibility is not guaranteed in future versions of the library.\n * It is recommended to avoid relying on the error API for critical functionality.\n *\n * _Available since v5.1._\n */\nlibrary Errors {\n    /**\n     * @dev The ETH balance of the account is not enough to perform the operation.\n     */\n    error InsufficientBalance(uint256 balance, uint256 needed);\n\n    /**\n     * @dev A call to an address target failed. The target may have reverted.\n     */\n    error FailedCall();\n\n    /**\n     * @dev The deployment failed.\n     */\n    error FailedDeployment();\n\n    /**\n     * @dev A necessary precompile is missing.\n     */\n    error MissingPrecompile(address);\n}\n"},{"file_path":"node_modules/@openzeppelin/contracts/utils/introspection/IERC165.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Interface of the ERC-165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[ERC].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n    /**\n     * @dev Returns true if this contract implements the interface defined by\n     * `interfaceId`. See the corresponding\n     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[ERC section]\n     * to learn more about how these ids are created.\n     *\n     * This function call must use less than 30 000 gas.\n     */\n    function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n"},{"file_path":"src/dependencies/CoreOwnable.sol","source_code":"// SPDX-License-Identifier: MIT\npragma solidity 0.8.28;\n\nimport {ICore} from \"../interfaces/ICore.sol\";\n\n/**\n    @title Core Ownable\n    @author Prisma Finance (with edits by Resupply Finance)\n    @notice Contracts inheriting `CoreOwnable` have the same owner as `Core`.\n            The ownership cannot be independently modified or renounced.\n */\ncontract CoreOwnable {\n    ICore public immutable core;\n\n    constructor(address _core) {\n        core = ICore(_core);\n    }\n\n    modifier onlyOwner() {\n        require(msg.sender == address(core), \"!core\");\n        _;\n    }\n\n    function owner() public view returns (address) {\n        return address(core);\n    }\n}"},{"file_path":"src/interfaces/IAuthHook.sol","source_code":"// SPDX-License-Identifier: MIT\npragma solidity 0.8.28;\n\ninterface IAuthHook {\n    function preHook(address operator, address target, bytes calldata data) external returns (bool);\n    function postHook(bytes memory result, address operator, address target, bytes calldata data) external returns (bool);\n}\n"},{"file_path":"src/interfaces/ICore.sol","source_code":"// SPDX-License-Identifier: MIT\npragma solidity 0.8.28;\n\nimport { IAuthHook } from './IAuthHook.sol';\n\ninterface ICore {\n    struct OperatorAuth {\n        bool authorized;\n        IAuthHook hook;\n    }\n\n    event VoterSet(address indexed newVoter);\n    event OperatorExecuted(address indexed caller, address indexed target, bytes data);\n    event OperatorSet(address indexed caller, address indexed target, bool authorized, bytes4 selector, IAuthHook authHook);\n\n    function execute(address target, bytes calldata data) external returns (bytes memory);\n    function epochLength() external view returns (uint256);\n    function startTime() external view returns (uint256);\n    function voter() external view returns (address);\n    function ownershipTransferDeadline() external view returns (uint256);\n    function pendingOwner() external view returns (address);\n    function setOperatorPermissions(\n        address caller,\n        address target,\n        bytes4 selector,\n        bool authorized,\n        IAuthHook authHook\n    ) external;\n    function setVoter(address newVoter) external;\n    function operatorPermissions(address caller, address target, bytes4 selector) external view returns (bool authorized, IAuthHook hook);\n}\n"},{"file_path":"src/interfaces/IMintable.sol","source_code":"// SPDX-License-Identifier: MIT\npragma solidity 0.8.28;\n\ninterface IMintable{\n    function mint(address _to, uint256 _amount) external;\n    function burn(address _from, uint256 _amount) external;\n}\n"},{"file_path":"src/interfaces/IResupplyPair.sol","source_code":"// SPDX-License-Identifier: MIT\npragma solidity 0.8.28;\n\ninterface IResupplyPair {\n    struct CurrentRateInfo {\n        uint64 lastTimestamp;\n        uint64 ratePerSec;\n        uint256 lastShares;\n    }\n    struct VaultAccount {\n        uint128 amount;\n        uint128 shares;\n    }\n\n    function addCollateral(uint256 _collateralAmount, address _borrower) external;\n    function addCollateralUnderlying(uint256 _collateralAmount, address _borrower) external;\n\n    function addInterest()\n        external\n        returns (uint256 _interestEarned, uint256 _feesAmount, uint256 _feesShare, uint64 _newRate);\n\n    function asset() external view returns (address);\n\n    function balanceOf(address account) external view returns (uint256);\n\n    function borrow(\n        uint256 _borrowAmount,\n        uint256 _collateralAmount,\n        address _receiver\n    ) external returns (uint256 _shares);\n\n    function changeFee(uint32 _newFee) external;\n\n    function mintFee() external view returns (uint256);\n    function liquidationFee() external view returns (uint256);\n    function protocolRedemptionFee() external view returns (uint256);\n\n    function collateral() external view returns (address);\n    function underlying() external view returns (address);\n\n    function currentRateInfo()\n        external\n        view\n        returns (\n            uint32 lastBlock,\n            uint64 lastTimestamp,\n            uint64 ratePerSec,\n            uint256 lastPrice,\n            uint256 lastShares\n        );\n    \n\n    function previewAddInterest()\n        external\n        view\n        returns (\n            uint256 _interestEarned,\n            CurrentRateInfo memory _newCurrentRateInfo,\n            uint256 _claimableFees,\n            VaultAccount memory _totalBorrow\n        );\n\n    function exchangeRateInfo() external view returns (address oracle, uint32 lastTimestamp, uint224 exchangeRate);\n\n    function getConstants()\n        external\n        pure\n        returns (\n            uint256 _LTV_PRECISION,\n            uint256 _LIQ_PRECISION,\n            uint256 _EXCHANGE_PRECISION,\n            uint256 _RATE_PRECISION\n        );\n\n    function getPairAccounting()\n        external\n        view\n        returns (\n            uint256 _claimableFees,\n            uint128 _totalBorrowAmount,\n            uint128 _totalBorrowShares,\n            uint256 _totalCollateral\n        );\n\n    function getUserSnapshot(\n        address _address\n    ) external view returns (uint256 _userBorrowShares, uint256 _userCollateralBalance);\n\n    function leveragedPosition(\n        address _swapperAddress,\n        uint256 _borrowAmount,\n        uint256 _initialUnderlyingAmount,\n        uint256 _amountCollateralOutMin,\n        address[] memory _path\n    ) external returns (uint256 _totalCollateralBalance);\n\n    function liquidate(\n        address _borrower\n    ) external returns (uint256 _collateralForLiquidator);\n\n    function maxLTV() external view returns (uint256);\n\n    function name() external view returns (string memory);\n\n    function owner() external view returns (address);\n\n    function pause() external;\n\n    function paused() external view returns (bool);\n\n    function rateCalculator() external view returns (address);\n\n    function borrowLimit() external view returns (uint256);\n    function totalAssetAvailable() external view returns (uint256);\n    function minimumLeftoverDebt() external view returns (uint256);\n    function minimumBorrowAmount() external view returns (uint256);\n    function minimumRedemption() external view returns (uint256);\n\n    function redeemCollateral(address _caller, uint256 _amount, uint256 _fee, address _receiver) external returns(address _collateralToken, uint256 _collateralReturned);\n\n    function removeCollateral(uint256 _collateralAmount, address _receiver) external;\n\n    function renounceOwnership() external;\n\n    function repayAsset(uint256 _shares, address _borrower) external returns (uint256 _amountToRepay);\n\n    function repayAssetWithCollateral(\n        address _swapperAddress,\n        uint256 _collateralToSwap,\n        uint256 _amountAssetOutMin,\n        address[] memory _path\n    ) external returns (uint256 _amountAssetOut);\n\n    function setApprovedBorrowers(address[] memory _borrowers, bool _approval) external;\n\n    function setApprovedLenders(address[] memory _lenders, bool _approval) external;\n\n    function setMaxOracleDelay(uint256 _newDelay) external;\n\n    function setSwapper(address _swapper, bool _approval) external;\n\n    function swappers(address) external view returns (bool);\n\n    function symbol() external view returns (string memory);\n\n    function toBorrowAmount(uint256 _shares, bool _roundUp, bool _previewInterest) external view returns (uint256);\n\n    function toBorrowShares(uint256 _amount, bool _roundUp, bool _previewInterest) external view returns (uint256);\n\n    function totalBorrow() external view returns (uint128 amount, uint128 shares);\n\n    function totalCollateral() external view returns (uint256);\n\n    function unpause() external;\n\n    function updateExchangeRate() external returns (uint256 _exchangeRate);\n\n    function userBorrowShares(address) external view returns (uint256);\n\n    function userCollateralBalance(address) external returns (uint256);\n\n    function version() external pure returns (uint256 _major, uint256 _minor, uint256 _patch);\n\n    function withdrawFees() external returns (uint256 _amountToTransfer);\n    function convexBooster() external view returns (address convexBooster);\n    function convexPid() external view returns (uint256 _convexPid);\n    function rewardLength() external view returns (uint256 _length);\n    function rewardMap(address _reward) external view returns (uint256 _rewardSlot);\n    function addExtraReward(address _token) external;\n\n    struct EarnedData {\n        address token;\n        uint256 amount;\n    }\n    function earned(address _account) external returns(EarnedData[] memory claimable);\n}\n"},{"file_path":"src/interfaces/IRewardHandler.sol","source_code":"// SPDX-License-Identifier: MIT\npragma solidity 0.8.28;\n\ninterface IRewardHandler{\n    function checkNewRewards(address _pair) external;\n    function claimRewards(address _pair) external;\n    function claimInsuranceRewards() external;\n    function setPairWeight(address _pair, uint256 _amount) external;\n    function queueInsuranceRewards() external;\n    function queueStakingRewards() external;\n    function pairEmissions() external view returns(address);\n    function insuranceEmissions() external view returns(address);\n    function insuranceRevenue() external view returns(address);\n    function debtEmissionsReceiver() external view returns(address);\n    function insuranceEmissionReceiver() external view returns(address);\n}\n"},{"file_path":"src/libraries/SafeERC20.sol","source_code":"// SPDX-License-Identifier: ISC\npragma solidity ^0.8.19;\n\nimport { IERC20 } from \"@openzeppelin/contracts/interfaces/IERC20.sol\";\nimport { SafeERC20 as OZSafeERC20 } from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\n// solhint-disable avoid-low-level-calls\n// solhint-disable max-line-length\n\n/// @title SafeERC20 provides helper functions for safe transfers as well as safe metadata access\n/// @author Library originally written by @Boring_Crypto github.com/boring_crypto, modified by Drake Evans (Frax Finance) github.com/drakeevans\n/// @dev original: https://github.com/boringcrypto/BoringSolidity/blob/fed25c5d43cb7ce20764cd0b838e21a02ea162e9/contracts/libraries/BoringERC20.sol\nlibrary SafeERC20 {\n    bytes4 private constant SIG_SYMBOL = 0x95d89b41; // symbol()\n    bytes4 private constant SIG_NAME = 0x06fdde03; // name()\n    bytes4 private constant SIG_DECIMALS = 0x313ce567; // decimals()\n\n    function returnDataToString(bytes memory data) internal pure returns (string memory) {\n        if (data.length >= 64) {\n            return abi.decode(data, (string));\n        } else if (data.length == 32) {\n            uint8 i = 0;\n            while (i < 32 && data[i] != 0) {\n                i++;\n            }\n            bytes memory bytesArray = new bytes(i);\n            for (i = 0; i < 32 && data[i] != 0; i++) {\n                bytesArray[i] = data[i];\n            }\n            return string(bytesArray);\n        } else {\n            return \"???\";\n        }\n    }\n\n    /// @notice Provides a safe ERC20.symbol version which returns '???' as fallback string.\n    /// @param token The address of the ERC-20 token contract.\n    /// @return (string) Token symbol.\n    function safeSymbol(IERC20 token) internal view returns (string memory) {\n        (bool success, bytes memory data) = address(token).staticcall(abi.encodeWithSelector(SIG_SYMBOL));\n        return success ? returnDataToString(data) : \"???\";\n    }\n\n    /// @notice Provides a safe ERC20.name version which returns '???' as fallback string.\n    /// @param token The address of the ERC-20 token contract.\n    /// @return (string) Token name.\n    function safeName(IERC20 token) internal view returns (string memory) {\n        (bool success, bytes memory data) = address(token).staticcall(abi.encodeWithSelector(SIG_NAME));\n        return success ? returnDataToString(data) : \"???\";\n    }\n\n    /// @notice Provides a safe ERC20.decimals version which returns '18' as fallback value.\n    /// @param token The address of the ERC-20 token contract.\n    /// @return (uint8) Token decimals.\n    function safeDecimals(IERC20 token) internal view returns (uint8) {\n        (bool success, bytes memory data) = address(token).staticcall(abi.encodeWithSelector(SIG_DECIMALS));\n        return success && data.length == 32 ? abi.decode(data, (uint8)) : 18;\n    }\n\n    function safeTransfer(IERC20 token, address to, uint256 value) internal {\n        OZSafeERC20.safeTransfer(token, to, value);\n    }\n\n    function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\n        OZSafeERC20.safeTransferFrom(token, from, to, value);\n    }\n}\n"}],"certified":false,"conflicting_implementations":null,"abi":[{"inputs":[{"internalType":"address","name":"_core","type":"address"},{"internalType":"address","name":"_token","type":"address"},{"internalType":"address","name":"_govToken","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"NameMustBeUnique","type":"error"},{"inputs":[{"internalType":"string","name":"key","type":"string"}],"name":"ProtectedKey","type":"error"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"SafeERC20FailedOperation","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"pairAddress","type":"address"}],"name":"AddPair","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address[]","name":"addresses","type":"address[]"}],"name":"DefaultSwappersSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"string","name":"key","type":"string"},{"indexed":true,"internalType":"address","name":"addr","type":"address"}],"name":"EntryUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"WithdrawTo","type":"event"},{"inputs":[],"name":"FEE_DEPOSIT","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"INSURANCE_POOL","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"L2_MANAGER","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"LIQUIDATION_HANDLER","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"REDEMPTION_HANDLER","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"REWARD_HANDLER","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"STAKER","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"TREASURY","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"VEST_MANAGER","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_pairAddress","type":"address"}],"name":"addPair","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_pair","type":"address"}],"name":"claimFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"claimInsuranceRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_pair","type":"address"}],"name":"claimRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"core","outputs":[{"internalType":"contract ICore","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"defaultSwappers","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"feeDeposit","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"key","type":"string"}],"name":"getAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAllAddresses","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAllKeys","outputs":[{"internalType":"string[]","name":"","type":"string[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAllPairAddresses","outputs":[{"internalType":"address[]","name":"_registeredPairs","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getProtectedKeys","outputs":[{"internalType":"string[]","name":"","type":"string[]"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"govToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"hashToKey","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"insurancePool","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"","type":"string"}],"name":"keyExists","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"l2manager","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"liquidationHandler","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_receiver","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"","type":"string"}],"name":"pairsByName","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"redemptionHandler","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"registeredPairs","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"registeredPairsLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardHandler","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"key","type":"string"},{"internalType":"address","name":"addr","type":"address"}],"name":"setAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_swappers","type":"address[]"}],"name":"setDefaultSwappers","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newAddress","type":"address"}],"name":"setFeeDeposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newAddress","type":"address"}],"name":"setInsurancePool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newAddress","type":"address"}],"name":"setL2Manager","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newAddress","type":"address"}],"name":"setLiquidationHandler","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newAddress","type":"address"}],"name":"setRedemptionHandler","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newAddress","type":"address"}],"name":"setRewardHandler","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newAddress","type":"address"}],"name":"setStaker","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newAddress","type":"address"}],"name":"setTreasury","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newAddress","type":"address"}],"name":"setVestManager","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"staker","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"token","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"treasury","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"vestManager","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_asset","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"address","name":"_to","type":"address"}],"name":"withdrawTo","outputs":[],"stateMutability":"nonpayable","type":"function"}],"is_changed_bytecode":false,"is_partially_verified":true,"constructor_args":"0x000000000000000000000000c07e000044f95655c11fda4cd37f70a94d7e0a7d00000000000000000000000057ab1e0003f623289cd798b1824be09a793e4bec000000000000000000000000419905009e4656fdc02418c7df35b1e61ed5f726"}