@venusprotocol/protocol-reserve 1.3.0 → 1.4.0-dev.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -0
- package/artifacts/@openzeppelin/contracts/access/AccessControl.sol/AccessControl.dbg.json +4 -0
- package/artifacts/@openzeppelin/contracts/access/AccessControl.sol/AccessControl.json +215 -0
- package/artifacts/@openzeppelin/contracts/access/IAccessControl.sol/IAccessControl.dbg.json +1 -1
- package/artifacts/@openzeppelin/contracts/access/Ownable.sol/Ownable.dbg.json +4 -0
- package/artifacts/@openzeppelin/contracts/access/Ownable.sol/Ownable.json +63 -0
- package/artifacts/@openzeppelin/contracts/interfaces/IERC1967.sol/IERC1967.dbg.json +4 -0
- package/artifacts/@openzeppelin/contracts/interfaces/IERC1967.sol/IERC1967.json +56 -0
- package/artifacts/@openzeppelin/contracts/interfaces/draft-IERC1822.sol/IERC1822Proxiable.dbg.json +4 -0
- package/artifacts/@openzeppelin/contracts/interfaces/draft-IERC1822.sol/IERC1822Proxiable.json +24 -0
- package/artifacts/@openzeppelin/contracts/proxy/ERC1967/ERC1967Upgrade.sol/ERC1967Upgrade.dbg.json +4 -0
- package/artifacts/@openzeppelin/contracts/proxy/ERC1967/ERC1967Upgrade.sol/ERC1967Upgrade.json +56 -0
- package/artifacts/@openzeppelin/contracts/proxy/Proxy.sol/Proxy.dbg.json +4 -0
- package/artifacts/@openzeppelin/contracts/proxy/Proxy.sol/Proxy.json +19 -0
- package/artifacts/@openzeppelin/contracts/proxy/beacon/BeaconProxy.sol/BeaconProxy.dbg.json +4 -0
- package/artifacts/@openzeppelin/contracts/proxy/beacon/BeaconProxy.sol/BeaconProxy.json +80 -0
- package/artifacts/@openzeppelin/contracts/proxy/beacon/IBeacon.sol/IBeacon.dbg.json +4 -0
- package/artifacts/{contracts/Interfaces/ComptrollerInterface.sol/ComptrollerInterface.json → @openzeppelin/contracts/proxy/beacon/IBeacon.sol/IBeacon.json} +5 -5
- package/artifacts/@openzeppelin/contracts/proxy/beacon/UpgradeableBeacon.sol/UpgradeableBeacon.dbg.json +4 -0
- package/artifacts/@openzeppelin/contracts/proxy/beacon/UpgradeableBeacon.sol/UpgradeableBeacon.json +113 -0
- package/artifacts/@openzeppelin/contracts/token/ERC20/ERC20.sol/ERC20.dbg.json +1 -1
- package/artifacts/@openzeppelin/contracts/token/ERC20/IERC20.sol/IERC20.dbg.json +1 -1
- package/artifacts/@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol/IERC20Metadata.dbg.json +1 -1
- package/artifacts/@openzeppelin/contracts/utils/Address.sol/Address.dbg.json +4 -0
- package/artifacts/@openzeppelin/contracts/utils/Address.sol/Address.json +10 -0
- package/artifacts/@openzeppelin/contracts/utils/Context.sol/Context.dbg.json +1 -1
- package/artifacts/@openzeppelin/contracts/utils/StorageSlot.sol/StorageSlot.dbg.json +4 -0
- package/artifacts/@openzeppelin/contracts/utils/StorageSlot.sol/StorageSlot.json +10 -0
- package/artifacts/@openzeppelin/contracts/utils/Strings.sol/Strings.dbg.json +4 -0
- package/artifacts/@openzeppelin/contracts/utils/Strings.sol/Strings.json +10 -0
- package/artifacts/@openzeppelin/contracts/utils/introspection/ERC165.sol/ERC165.dbg.json +4 -0
- package/artifacts/@openzeppelin/contracts/utils/introspection/ERC165.sol/ERC165.json +30 -0
- package/artifacts/@openzeppelin/contracts/utils/introspection/IERC165.sol/IERC165.dbg.json +4 -0
- package/artifacts/@openzeppelin/contracts/utils/introspection/IERC165.sol/IERC165.json +30 -0
- package/artifacts/@openzeppelin/contracts/utils/math/Math.sol/Math.dbg.json +4 -0
- package/artifacts/@openzeppelin/contracts/utils/math/Math.sol/Math.json +10 -0
- package/artifacts/@openzeppelin/contracts/utils/math/SignedMath.sol/SignedMath.dbg.json +4 -0
- package/artifacts/@openzeppelin/contracts/utils/math/SignedMath.sol/SignedMath.json +10 -0
- package/artifacts/@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol/Ownable2StepUpgradeable.dbg.json +1 -1
- package/artifacts/@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol/OwnableUpgradeable.dbg.json +1 -1
- package/artifacts/@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol/Initializable.dbg.json +1 -1
- package/artifacts/@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol/PausableUpgradeable.dbg.json +4 -0
- package/artifacts/@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol/PausableUpgradeable.json +63 -0
- package/artifacts/@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol/ReentrancyGuardUpgradeable.dbg.json +1 -1
- package/artifacts/@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol/IERC20Upgradeable.dbg.json +1 -1
- package/artifacts/@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20PermitUpgradeable.sol/IERC20PermitUpgradeable.dbg.json +1 -1
- package/artifacts/@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol/SafeERC20Upgradeable.dbg.json +1 -1
- package/artifacts/@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol/AddressUpgradeable.dbg.json +1 -1
- package/artifacts/@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol/ContextUpgradeable.dbg.json +1 -1
- package/artifacts/@venusprotocol/governance-contracts/contracts/Governance/AccessControlledV8.sol/AccessControlledV8.dbg.json +1 -1
- package/artifacts/@venusprotocol/governance-contracts/contracts/Governance/IAccessControlManagerV8.sol/IAccessControlManagerV8.dbg.json +1 -1
- package/artifacts/@venusprotocol/oracle/contracts/ResilientOracle.sol/ResilientOracle.dbg.json +4 -0
- package/artifacts/@venusprotocol/oracle/contracts/ResilientOracle.sol/ResilientOracle.json +649 -0
- package/artifacts/@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol/BoundValidatorInterface.dbg.json +4 -0
- package/artifacts/@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol/BoundValidatorInterface.json +40 -0
- package/artifacts/@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol/OracleInterface.dbg.json +4 -0
- package/artifacts/@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol/OracleInterface.json +30 -0
- package/artifacts/@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol/ResilientOracleInterface.dbg.json +4 -0
- package/artifacts/@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol/ResilientOracleInterface.json +75 -0
- package/artifacts/@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol/TwapInterface.dbg.json +4 -0
- package/artifacts/@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol/TwapInterface.json +49 -0
- package/artifacts/@venusprotocol/oracle/contracts/interfaces/VBep20Interface.sol/VBep20Interface.dbg.json +4 -0
- package/artifacts/@venusprotocol/oracle/contracts/interfaces/VBep20Interface.sol/VBep20Interface.json +246 -0
- package/artifacts/@venusprotocol/solidity-utilities/contracts/MaxLoopsLimitHelper.sol/MaxLoopsLimitHelper.dbg.json +1 -1
- package/artifacts/build-info/e6962244d9988e3e4bb55e591cf3b5d8.json +1 -0
- package/artifacts/contracts/Interfaces/IComptroller.sol/IComptroller.dbg.json +4 -0
- package/artifacts/contracts/Interfaces/IComptroller.sol/IComptroller.json +56 -0
- package/artifacts/contracts/Interfaces/IConverterNetwork.sol/IConverterNetwork.dbg.json +4 -0
- package/artifacts/contracts/Interfaces/IConverterNetwork.sol/IConverterNetwork.json +127 -0
- package/artifacts/contracts/Interfaces/IIncomeDestination.sol/IIncomeDestination.dbg.json +1 -1
- package/artifacts/contracts/Interfaces/IPoolRegistry.sol/IPoolRegistry.dbg.json +4 -0
- package/artifacts/contracts/Interfaces/IPoolRegistry.sol/IPoolRegistry.json +54 -0
- package/artifacts/contracts/Interfaces/IProtocolShareReserve.sol/IProtocolShareReserve.dbg.json +1 -1
- package/artifacts/contracts/Interfaces/IRiskFund.sol/IRiskFund.dbg.json +4 -0
- package/artifacts/contracts/Interfaces/IRiskFund.sol/IRiskFund.json +77 -0
- package/artifacts/contracts/Interfaces/IRiskFund.sol/IRiskFundGetters.dbg.json +4 -0
- package/artifacts/contracts/Interfaces/IRiskFund.sol/IRiskFundGetters.json +24 -0
- package/artifacts/contracts/Interfaces/IRiskFundConverter.sol/IRiskFundConverter.dbg.json +4 -0
- package/artifacts/contracts/Interfaces/{PoolRegistryInterface.sol/PoolRegistryInterface.json → IRiskFundConverter.sol/IRiskFundConverter.json} +23 -10
- package/artifacts/contracts/Interfaces/IShortfall.sol/IShortfall.dbg.json +4 -0
- package/artifacts/contracts/Interfaces/IShortfall.sol/IShortfall.json +24 -0
- package/artifacts/contracts/Interfaces/IVToken.sol/IVToken.dbg.json +1 -1
- package/artifacts/contracts/Interfaces/IXVSVault.sol/IXVSVault.dbg.json +4 -0
- package/artifacts/contracts/Interfaces/IXVSVault.sol/IXVSVault.json +24 -0
- package/artifacts/contracts/ProtocolReserve/ProtocolShareReserve.sol/ProtocolShareReserve.dbg.json +1 -1
- package/artifacts/contracts/ProtocolReserve/ProtocolShareReserve.sol/ProtocolShareReserve.json +7 -2
- package/artifacts/contracts/ProtocolReserve/RiskFundStorage.sol/MaxLoopsLimitHelpersStorage.dbg.json +4 -0
- package/artifacts/contracts/ProtocolReserve/RiskFundStorage.sol/MaxLoopsLimitHelpersStorage.json +24 -0
- package/artifacts/contracts/ProtocolReserve/RiskFundStorage.sol/ReserveHelpersStorage.dbg.json +4 -0
- package/artifacts/contracts/ProtocolReserve/RiskFundStorage.sol/ReserveHelpersStorage.json +139 -0
- package/artifacts/contracts/ProtocolReserve/RiskFundStorage.sol/RiskFundV1Storage.dbg.json +4 -0
- package/artifacts/contracts/ProtocolReserve/RiskFundStorage.sol/RiskFundV1Storage.json +178 -0
- package/artifacts/contracts/ProtocolReserve/RiskFundStorage.sol/RiskFundV2Storage.dbg.json +4 -0
- package/artifacts/contracts/ProtocolReserve/RiskFundStorage.sol/RiskFundV2Storage.json +191 -0
- package/artifacts/contracts/ProtocolReserve/RiskFundV2.sol/RiskFundV2.dbg.json +4 -0
- package/artifacts/contracts/ProtocolReserve/RiskFundV2.sol/RiskFundV2.json +630 -0
- package/artifacts/contracts/ProtocolReserve/XVSVaultTreasury.sol/XVSVaultTreasury.dbg.json +4 -0
- package/artifacts/contracts/ProtocolReserve/XVSVaultTreasury.sol/XVSVaultTreasury.json +315 -0
- package/artifacts/contracts/Test/Mocks/MockACM.sol/MockACM.dbg.json +4 -0
- package/artifacts/contracts/Test/Mocks/MockACM.sol/MockACM.json +369 -0
- package/artifacts/contracts/Test/Mocks/MockArraySorter.sol/MockArraySorter.dbg.json +4 -0
- package/artifacts/contracts/Test/Mocks/MockArraySorter.sol/MockArraySorter.json +40 -0
- package/artifacts/contracts/Test/Mocks/MockConverter.sol/MockConverter.dbg.json +4 -0
- package/artifacts/contracts/Test/Mocks/MockConverter.sol/MockConverter.json +1395 -0
- package/artifacts/contracts/Test/Mocks/MockDeflationaryToken.sol/MockDeflatingToken.dbg.json +4 -0
- package/artifacts/contracts/Test/Mocks/MockDeflationaryToken.sol/MockDeflatingToken.json +332 -0
- package/artifacts/contracts/Test/Mocks/MockRiskFundConverter.sol/MockRiskFundConverter.dbg.json +4 -0
- package/artifacts/contracts/Test/Mocks/MockRiskFundConverter.sol/MockRiskFundConverter.json +1761 -0
- package/artifacts/contracts/Test/Mocks/MockToken.sol/MockToken.dbg.json +1 -1
- package/artifacts/contracts/Test/Mocks/MockToken.sol/MockToken.json +20 -2
- package/artifacts/contracts/TokenConverter/AbstractTokenConverter.sol/AbstractTokenConverter.dbg.json +4 -0
- package/artifacts/contracts/TokenConverter/AbstractTokenConverter.sol/AbstractTokenConverter.json +1276 -0
- package/artifacts/contracts/TokenConverter/ConverterNetwork.sol/ConverterNetwork.dbg.json +4 -0
- package/artifacts/contracts/TokenConverter/ConverterNetwork.sol/ConverterNetwork.json +457 -0
- package/artifacts/contracts/TokenConverter/IAbstractTokenConverter.sol/IAbstractTokenConverter.dbg.json +4 -0
- package/artifacts/contracts/TokenConverter/IAbstractTokenConverter.sol/IAbstractTokenConverter.json +446 -0
- package/artifacts/contracts/TokenConverter/RiskFundConverter.sol/RiskFundConverter.dbg.json +4 -0
- package/artifacts/contracts/TokenConverter/RiskFundConverter.sol/RiskFundConverter.json +1631 -0
- package/artifacts/contracts/TokenConverter/SingleTokenConverter.sol/SingleTokenConverter.dbg.json +4 -0
- package/artifacts/contracts/TokenConverter/SingleTokenConverter.sol/SingleTokenConverter.json +1390 -0
- package/contracts/Interfaces/IComptroller.sol +10 -0
- package/contracts/Interfaces/IConverterNetwork.sol +46 -0
- package/contracts/Interfaces/IPoolRegistry.sol +10 -0
- package/contracts/Interfaces/IRiskFund.sol +28 -0
- package/contracts/Interfaces/IRiskFundConverter.sol +8 -0
- package/contracts/Interfaces/IShortfall.sol +11 -0
- package/contracts/Interfaces/IXVSVault.sol +9 -0
- package/contracts/ProtocolReserve/ProtocolShareReserve.sol +15 -12
- package/contracts/ProtocolReserve/RiskFundStorage.sol +67 -0
- package/contracts/ProtocolReserve/RiskFundV2.sol +253 -0
- package/contracts/ProtocolReserve/XVSVaultTreasury.sol +95 -0
- package/contracts/Test/Mocks/MockACM.sol +94 -0
- package/contracts/Test/Mocks/MockArraySorter.sol +14 -0
- package/contracts/Test/Mocks/MockConverter.sol +70 -0
- package/contracts/Test/Mocks/MockDeflationaryToken.sol +113 -0
- package/contracts/Test/Mocks/MockRiskFundConverter.sol +45 -0
- package/contracts/Test/Mocks/MockToken.sol +4 -0
- package/contracts/Test/imports.sol +11 -0
- package/contracts/TokenConverter/AbstractTokenConverter.sol +1167 -0
- package/contracts/TokenConverter/ConverterNetwork.sol +243 -0
- package/contracts/TokenConverter/IAbstractTokenConverter.sol +178 -0
- package/contracts/TokenConverter/RiskFundConverter.sol +449 -0
- package/contracts/TokenConverter/SingleTokenConverter.sol +103 -0
- package/contracts/Utils/ArrayHelpers.sol +41 -0
- package/deployments/bscmainnet/BTCBPrimeConverter.json +218 -0
- package/deployments/bscmainnet/ConverterNetwork.json +723 -0
- package/deployments/bscmainnet/ConverterNetwork_Implementation.json +823 -0
- package/deployments/bscmainnet/ConverterNetwork_Proxy.json +277 -0
- package/deployments/bscmainnet/ETHPrimeConverter.json +218 -0
- package/deployments/bscmainnet/ProtocolShareReserve_Implementation.json +89 -73
- package/deployments/bscmainnet/RiskFundConverter.json +2035 -0
- package/deployments/bscmainnet/RiskFundConverter_Implementation.json +2563 -0
- package/deployments/bscmainnet/RiskFundConverter_Proxy.json +403 -0
- package/deployments/bscmainnet/RiskFundV2.json +1049 -0
- package/deployments/bscmainnet/SingleTokenConverterBeacon.json +206 -0
- package/deployments/bscmainnet/SingleTokenConverterImp.json +2164 -0
- package/deployments/bscmainnet/USDCPrimeConverter.json +218 -0
- package/deployments/bscmainnet/USDTPrimeConverter.json +218 -0
- package/deployments/bscmainnet/XVSVaultConverter.json +218 -0
- package/deployments/bscmainnet/XVSVaultTreasury.json +579 -0
- package/deployments/bscmainnet/XVSVaultTreasury_Implementation.json +603 -0
- package/deployments/bscmainnet/XVSVaultTreasury_Proxy.json +281 -0
- package/deployments/bscmainnet/solcInputs/d02e743d886d63634298edb2c3d7a019.json +123 -0
- package/deployments/bscmainnet/solcInputs/ee8827a99e03cdf6f6a94fb8782ddf44.json +228 -0
- package/deployments/bscmainnet.json +8927 -873
- package/deployments/bscmainnet_addresses.json +19 -2
- package/deployments/bsctestnet/BTCBPrimeConverter.json +218 -0
- package/deployments/bsctestnet/ConverterNetwork.json +723 -0
- package/deployments/bsctestnet/ConverterNetwork_Implementation.json +823 -0
- package/deployments/bsctestnet/ConverterNetwork_Proxy.json +277 -0
- package/deployments/bsctestnet/ETHPrimeConverter.json +218 -0
- package/deployments/bsctestnet/ProtocolShareReserve_Implementation.json +89 -73
- package/deployments/bsctestnet/RiskFundConverter.json +2035 -0
- package/deployments/bsctestnet/RiskFundConverter_Implementation.json +2563 -0
- package/deployments/bsctestnet/RiskFundConverter_Proxy.json +403 -0
- package/deployments/bsctestnet/RiskFundV2.json +1049 -0
- package/deployments/bsctestnet/SingleTokenConverterBeacon.json +206 -0
- package/deployments/bsctestnet/SingleTokenConverterImp.json +2164 -0
- package/deployments/bsctestnet/USDCPrimeConverter.json +218 -0
- package/deployments/bsctestnet/USDTPrimeConverter.json +218 -0
- package/deployments/bsctestnet/XVSVaultConverter.json +218 -0
- package/deployments/bsctestnet/XVSVaultTreasury.json +579 -0
- package/deployments/bsctestnet/XVSVaultTreasury_Implementation.json +603 -0
- package/deployments/bsctestnet/XVSVaultTreasury_Proxy.json +281 -0
- package/deployments/bsctestnet/solcInputs/d02e743d886d63634298edb2c3d7a019.json +123 -0
- package/deployments/bsctestnet/solcInputs/ee8827a99e03cdf6f6a94fb8782ddf44.json +228 -0
- package/deployments/bsctestnet.json +8927 -873
- package/deployments/bsctestnet_addresses.json +19 -2
- package/dist/deploy/{1-deploy.d.ts → 001-psr.d.ts} +1 -1
- package/dist/deploy/001-psr.d.ts.map +1 -0
- package/dist/deploy/{1-deploy.js → 001-psr.js} +2 -2
- package/dist/deploy/001-psr.js.map +1 -0
- package/dist/deploy/002-risk-fund-converter.d.ts +4 -0
- package/dist/deploy/002-risk-fund-converter.d.ts.map +1 -0
- package/dist/deploy/002-risk-fund-converter.js +78 -0
- package/dist/deploy/002-risk-fund-converter.js.map +1 -0
- package/dist/deploy/003-xvs-vault-teasury.d.ts +7 -0
- package/dist/deploy/003-xvs-vault-teasury.d.ts.map +1 -0
- package/dist/deploy/003-xvs-vault-teasury.js +45 -0
- package/dist/deploy/003-xvs-vault-teasury.js.map +1 -0
- package/dist/deploy/004-single-token-converter.d.ts +4 -0
- package/dist/deploy/004-single-token-converter.d.ts.map +1 -0
- package/dist/deploy/004-single-token-converter.js +65 -0
- package/dist/deploy/004-single-token-converter.js.map +1 -0
- package/dist/deploy/005-converter-network.d.ts +7 -0
- package/dist/deploy/005-converter-network.d.ts.map +1 -0
- package/dist/deploy/005-converter-network.js +43 -0
- package/dist/deploy/005-converter-network.js.map +1 -0
- package/dist/hardhat.config.d.ts.map +1 -1
- package/dist/hardhat.config.js +6 -0
- package/dist/hardhat.config.js.map +1 -1
- package/dist/helpers/utils.d.ts +1 -0
- package/dist/helpers/utils.d.ts.map +1 -1
- package/dist/helpers/utils.js +2 -1
- package/dist/helpers/utils.js.map +1 -1
- package/package.json +19 -16
- package/typechain/AbstractTokenConverter.d.ts +1775 -0
- package/typechain/AccessControl.d.ts +388 -0
- package/typechain/BeaconProxy.d.ts +126 -0
- package/typechain/BoundValidatorInterface.d.ts +126 -0
- package/typechain/ConverterNetwork.d.ts +723 -0
- package/typechain/{PoolRegistryInterface.d.ts → ERC165.d.ts} +20 -25
- package/typechain/ERC1967Upgrade.d.ts +126 -0
- package/typechain/IAbstractTokenConverter.d.ts +773 -0
- package/typechain/IBeacon.d.ts +101 -0
- package/typechain/IComptroller.d.ts +136 -0
- package/typechain/IConverterNetwork.d.ts +292 -0
- package/typechain/IERC165.d.ts +116 -0
- package/typechain/{ComptrollerInterface.d.ts → IERC1822Proxiable.d.ts} +11 -11
- package/typechain/IERC1967.d.ts +126 -0
- package/typechain/IPoolRegistry.d.ts +155 -0
- package/typechain/IRiskFund.d.ts +200 -0
- package/typechain/IRiskFundConverter.d.ts +138 -0
- package/typechain/IRiskFundGetters.d.ts +103 -0
- package/typechain/IShortfall.d.ts +110 -0
- package/typechain/IXVSVault.d.ts +95 -0
- package/typechain/MaxLoopsLimitHelpersStorage.d.ts +101 -0
- package/typechain/MockACM.d.ts +615 -0
- package/typechain/MockArraySorter.d.ts +118 -0
- package/typechain/MockConverter.d.ts +1969 -0
- package/typechain/MockDeflatingToken.d.ts +486 -0
- package/typechain/MockRiskFundConverter.d.ts +2479 -0
- package/typechain/MockToken.d.ts +36 -0
- package/typechain/OracleInterface.d.ts +98 -0
- package/typechain/Ownable.d.ts +181 -0
- package/typechain/PausableUpgradeable.d.ts +129 -0
- package/typechain/Proxy.d.ts +78 -0
- package/typechain/ReserveHelpersStorage.d.ts +300 -0
- package/typechain/ResilientOracle.d.ts +1034 -0
- package/typechain/ResilientOracleInterface.d.ts +192 -0
- package/typechain/RiskFundConverter.d.ts +2235 -0
- package/typechain/RiskFundV1Storage.d.ts +353 -0
- package/typechain/RiskFundV2.d.ts +965 -0
- package/typechain/RiskFundV2Storage.d.ts +372 -0
- package/typechain/SingleTokenConverter.d.ts +1944 -0
- package/typechain/TwapInterface.d.ts +124 -0
- package/typechain/UpgradeableBeacon.d.ts +240 -0
- package/typechain/VBep20Interface.d.ts +379 -0
- package/typechain/XVSVaultTreasury.d.ts +515 -0
- package/typechain/factories/AbstractTokenConverter__factory.ts +1297 -0
- package/typechain/factories/AccessControl__factory.ts +227 -0
- package/typechain/factories/BeaconProxy__factory.ts +133 -0
- package/typechain/factories/BoundValidatorInterface__factory.ts +59 -0
- package/typechain/factories/ConverterNetwork__factory.ts +502 -0
- package/typechain/factories/ERC165__factory.ts +39 -0
- package/typechain/factories/ERC1967Upgrade__factory.ts +71 -0
- package/typechain/factories/IAbstractTokenConverter__factory.ts +466 -0
- package/typechain/factories/IBeacon__factory.ts +36 -0
- package/typechain/factories/IComptroller__factory.ts +68 -0
- package/typechain/factories/IConverterNetwork__factory.ts +142 -0
- package/typechain/factories/{ComptrollerInterface__factory.ts → IERC165__factory.ts} +14 -15
- package/typechain/factories/IERC1822Proxiable__factory.ts +39 -0
- package/typechain/factories/IERC1967__factory.ts +68 -0
- package/typechain/factories/IPoolRegistry__factory.ts +66 -0
- package/typechain/factories/{PoolRegistryInterface__factory.ts → IRiskFundConverter__factory.ts} +28 -19
- package/typechain/factories/IRiskFundGetters__factory.ts +39 -0
- package/typechain/factories/IRiskFund__factory.ts +89 -0
- package/typechain/factories/IShortfall__factory.ts +36 -0
- package/typechain/factories/IXVSVault__factory.ts +36 -0
- package/typechain/factories/MaxLoopsLimitHelpersStorage__factory.ts +75 -0
- package/typechain/factories/MockACM__factory.ts +411 -0
- package/typechain/factories/MockArraySorter__factory.ts +85 -0
- package/typechain/factories/MockConverter__factory.ts +1439 -0
- package/typechain/factories/MockDeflatingToken__factory.ts +389 -0
- package/typechain/factories/MockRiskFundConverter__factory.ts +1828 -0
- package/typechain/factories/MockToken__factory.ts +19 -1
- package/typechain/factories/OracleInterface__factory.ts +45 -0
- package/typechain/factories/Ownable__factory.ts +75 -0
- package/typechain/factories/PausableUpgradeable__factory.ts +78 -0
- package/typechain/factories/ProtocolShareReserve__factory.ts +6 -1
- package/typechain/factories/Proxy__factory.ts +28 -0
- package/typechain/factories/ReserveHelpersStorage__factory.ts +188 -0
- package/typechain/factories/ResilientOracleInterface__factory.ts +94 -0
- package/typechain/factories/ResilientOracle__factory.ts +710 -0
- package/typechain/factories/RiskFundConverter__factory.ts +1694 -0
- package/typechain/factories/RiskFundV1Storage__factory.ts +223 -0
- package/typechain/factories/RiskFundV2Storage__factory.ts +236 -0
- package/typechain/factories/RiskFundV2__factory.ts +672 -0
- package/typechain/factories/SingleTokenConverter__factory.ts +1441 -0
- package/typechain/factories/TwapInterface__factory.ts +61 -0
- package/typechain/factories/UpgradeableBeacon__factory.ts +163 -0
- package/typechain/factories/VBep20Interface__factory.ts +261 -0
- package/typechain/factories/XVSVaultTreasury__factory.ts +365 -0
- package/typechain/index.ts +84 -4
- package/artifacts/build-info/ac790619cb42a0f08af77d9ea733874e.json +0 -1
- package/artifacts/contracts/Interfaces/ComptrollerInterface.sol/ComptrollerInterface.dbg.json +0 -4
- package/artifacts/contracts/Interfaces/PoolRegistryInterface.sol/PoolRegistryInterface.dbg.json +0 -4
- package/contracts/Interfaces/ComptrollerInterface.sol +0 -6
- package/contracts/Interfaces/PoolRegistryInterface.sol +0 -7
- package/dist/deploy/1-deploy.d.ts.map +0 -1
- package/dist/deploy/1-deploy.js.map +0 -1
|
@@ -0,0 +1,1167 @@
|
|
|
1
|
+
// SPDX-License-Identifier: BSD-3-Clause
|
|
2
|
+
pragma solidity 0.8.13;
|
|
3
|
+
|
|
4
|
+
import { ReentrancyGuardUpgradeable } from "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol";
|
|
5
|
+
import { SafeERC20Upgradeable } from "@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol";
|
|
6
|
+
import { AccessControlledV8 } from "@venusprotocol/governance-contracts/contracts/Governance/AccessControlledV8.sol";
|
|
7
|
+
import { IERC20Upgradeable } from "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol";
|
|
8
|
+
import { ResilientOracle } from "@venusprotocol/oracle/contracts/ResilientOracle.sol";
|
|
9
|
+
import { ensureNonzeroAddress, ensureNonzeroValue } from "@venusprotocol/solidity-utilities/contracts/validators.sol";
|
|
10
|
+
import { MANTISSA_ONE, EXP_SCALE } from "@venusprotocol/solidity-utilities/contracts/constants.sol";
|
|
11
|
+
|
|
12
|
+
import { IAbstractTokenConverter } from "./IAbstractTokenConverter.sol";
|
|
13
|
+
import { IConverterNetwork } from "../Interfaces/IConverterNetwork.sol";
|
|
14
|
+
|
|
15
|
+
/// @title AbstractTokenConverter
|
|
16
|
+
/// @author Venus
|
|
17
|
+
/// @notice Abstract contract will be extended by SingleTokenConverter and RiskFundConverter
|
|
18
|
+
/*
|
|
19
|
+
* This contract specifies four functions for converting tokens, each applicable under following circumstances:
|
|
20
|
+
*
|
|
21
|
+
* Case I: TokenIn -> deflationary token, TokenOut -> deflationary token
|
|
22
|
+
* In this scenario, functions supporting fees can only be utilized to convert tokens which are:
|
|
23
|
+
* a. convertExactTokensSupportingFeeOnTransferTokens
|
|
24
|
+
* b. convertForExactTokensSupportingFeeOnTransferTokens
|
|
25
|
+
*
|
|
26
|
+
* Case II: TokenIn -> deflationary token, TokenOut -> non-deflationary token
|
|
27
|
+
* In this scenario, functions supporting fee can only be utilized to convert tokens which are:
|
|
28
|
+
* similar to Case I.
|
|
29
|
+
*
|
|
30
|
+
* Case III: TokenIn -> non-deflationary token, TokenOut -> deflationary token
|
|
31
|
+
* In this scenario, functions with or without supporting fee can be utilized to convert tokens which are:
|
|
32
|
+
* a. convertExactTokens
|
|
33
|
+
* b. convertForExactTokens
|
|
34
|
+
* c. convertExactTokensSupportingFeeOnTransferTokens
|
|
35
|
+
* d. convertForExactTokensSupportingFeeOnTransferTokens
|
|
36
|
+
*
|
|
37
|
+
* Case IV: TokenIn -> non-deflationary token, TokenOut -> non-deflationary token
|
|
38
|
+
* In this scenario, functions with or without supporting fee can be utilized to convert tokens which are:
|
|
39
|
+
* similar to Case III.
|
|
40
|
+
*
|
|
41
|
+
* ------------------------------------------------------------------------------------------------------------------------------------
|
|
42
|
+
* Example 1:-
|
|
43
|
+
* tokenInAddress - 0xaaaa.....
|
|
44
|
+
* tokenOutAddress - 0xbbbb.....
|
|
45
|
+
* tokenInAmount - 100
|
|
46
|
+
* tokenOutMinAmount - minimum amount desired by the user(let's say 70)
|
|
47
|
+
* Here user can use `convertExactTokens` or `convertExactTokensSupportingFeeOnTransferTokens`, if tokenIn is deflationary
|
|
48
|
+
* then `convertExactTokensSupportingFeeOnTransferTokens` should be used(let's suppose `convertExactTokens` is used).
|
|
49
|
+
* Now first tokenInAddress tokens will be transferred from the user to the contract, on the basis of amount
|
|
50
|
+
* received(as tokenInAddress can be deflationary token) tokenAmountOut will be calculated and will be transferred
|
|
51
|
+
* to the user and if amount sent is less than tokenOutMinAmount, tx will revert. If amount sent is satisfied(let's say
|
|
52
|
+
* 80 or even 70) then at last the actual amount received and the amount that was supposed to be received by the contract will
|
|
53
|
+
* be compared, if they differ then the whole tx will revert as user was supposed to use `convertExactTokensSupportingFeeOnTransferTokens`
|
|
54
|
+
* function for tokenIn as deflationary token.
|
|
55
|
+
*
|
|
56
|
+
* Example 2:-
|
|
57
|
+
* tokenInAddress - 0xaaaa.....
|
|
58
|
+
* tokenOutAddress - 0xbbbb.....
|
|
59
|
+
* tokenInMaxAmount - maximum amount user is willing to provide(let's say 100)
|
|
60
|
+
* tokenOutAmount - 70
|
|
61
|
+
* Here user can use `convertForExactTokens` or `convertForExactTokensSupportingFeeOnTransferTokens`, if tokenIn is deflationary
|
|
62
|
+
* then `convertForExactTokensSupportingFeeOnTransferTokens` should be used(let's suppose `convertForExactTokens` is used),
|
|
63
|
+
* which on the basis of tokenOutAmount provided will calculate tokenInAmount based on the tokens prices and will transfer
|
|
64
|
+
* tokens from the user to the contract, now the actual amount received(as tokenInAddress can be deflationary token) will be
|
|
65
|
+
* compared with tokenInMaxAmount if it is greater, tx will revert. If In amount is satisfied(let's say 90 or even 100) then
|
|
66
|
+
* new tokenOutAmount will be calculated, and tokenOutAddress tokens will be transferred to the user, but at last the
|
|
67
|
+
* old tokenOutAmount and new tokenOutAmount will be compared and if they differ whole tx will revert, because user was
|
|
68
|
+
* supposed to use `convertForExactTokensSupportingFeeOnTransferTokens` function for tokenIn as deflationary token.
|
|
69
|
+
* ------------------------------------------------------------------------------------------------------------------------------------
|
|
70
|
+
*
|
|
71
|
+
* This contract also supports private conversion between the converters:
|
|
72
|
+
* Private conversions:
|
|
73
|
+
* Private conversions is designed in order to convert the maximum amount of tokens received from PSR(to any converter) between
|
|
74
|
+
* existing converters to save incentive and lower the dependency of users for conversion. So Private Conversion will be executed
|
|
75
|
+
* by converters on it's own whenever funds are received from PSR. No incentive will be offered during private conversion.
|
|
76
|
+
*
|
|
77
|
+
* It will execute on updateAssetsState() function call in Converter Contracts. After this function call, converter will first
|
|
78
|
+
* check for the amount received. If base asset is received then it will be directly sent to the destination address and no private
|
|
79
|
+
* conversion will happen otherwise converter will interact with ConverterNetwork contract to find other valid converters who are providing the conversion for:
|
|
80
|
+
*
|
|
81
|
+
* tokenAddressIn: As asset received by that converter on updateAssetsState() function call.
|
|
82
|
+
* tokenAddressOut: As base asset of that converter.
|
|
83
|
+
*
|
|
84
|
+
* ConverterNetwork:
|
|
85
|
+
* This contract will contain all the converters, and will provide valid converters which can perform the execution according to tokenAddressIn
|
|
86
|
+
* and tokenAddressOut provided.
|
|
87
|
+
*
|
|
88
|
+
* findTokenConverters():
|
|
89
|
+
* It will return an array of converter addresses along with their corresponding balances, sorted in descending order based on the converter's balances
|
|
90
|
+
* relative to tokenAddressOut. This function filter the converter addresses on the basis of the conversionAccess(for users).
|
|
91
|
+
*
|
|
92
|
+
* findTokenConvertersForConverters():
|
|
93
|
+
* It will return an array of converter addresses along with their corresponding balances, sorted in descending order based on the converter's balances
|
|
94
|
+
* relative to tokenAddressOut. This function filter the converter addresses on the basis of the conversionAccess(for converters).
|
|
95
|
+
*/
|
|
96
|
+
|
|
97
|
+
/// @custom:security-contact https://github.com/VenusProtocol/protocol-reserve#discussion
|
|
98
|
+
abstract contract AbstractTokenConverter is AccessControlledV8, IAbstractTokenConverter, ReentrancyGuardUpgradeable {
|
|
99
|
+
using SafeERC20Upgradeable for IERC20Upgradeable;
|
|
100
|
+
|
|
101
|
+
/// @notice Maximum incentive could be
|
|
102
|
+
uint256 public constant MAX_INCENTIVE = 0.5e18;
|
|
103
|
+
|
|
104
|
+
/// @notice Min amount to convert for private conversions. Defined in USD, with 18 decimals
|
|
105
|
+
uint256 public minAmountToConvert;
|
|
106
|
+
|
|
107
|
+
/// @notice Venus price oracle contract
|
|
108
|
+
ResilientOracle public priceOracle;
|
|
109
|
+
|
|
110
|
+
/// @notice conversion configurations for the existing pairs
|
|
111
|
+
/// @dev tokenAddressIn => tokenAddressOut => ConversionConfig
|
|
112
|
+
mapping(address => mapping(address => ConversionConfig)) public conversionConfigurations;
|
|
113
|
+
|
|
114
|
+
/// @notice Address that all incoming tokens are transferred to
|
|
115
|
+
address public destinationAddress;
|
|
116
|
+
|
|
117
|
+
/// @notice Boolean for if conversion is paused
|
|
118
|
+
bool public conversionPaused;
|
|
119
|
+
|
|
120
|
+
/// @notice Address of the converterNetwork contract
|
|
121
|
+
IConverterNetwork public converterNetwork;
|
|
122
|
+
|
|
123
|
+
/// @dev This empty reserved space is put in place to allow future versions to add new
|
|
124
|
+
/// variables without shifting down storage in the inheritance chain.
|
|
125
|
+
/// See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
|
|
126
|
+
uint256[45] private __gap;
|
|
127
|
+
|
|
128
|
+
/// @notice Emitted when config is updated for tokens pair
|
|
129
|
+
event ConversionConfigUpdated(
|
|
130
|
+
address indexed tokenAddressIn,
|
|
131
|
+
address indexed tokenAddressOut,
|
|
132
|
+
uint256 oldIncentive,
|
|
133
|
+
uint256 newIncentive,
|
|
134
|
+
ConversionAccessibility oldAccess,
|
|
135
|
+
ConversionAccessibility newAccess
|
|
136
|
+
);
|
|
137
|
+
/// @notice Emitted when price oracle address is updated
|
|
138
|
+
event PriceOracleUpdated(ResilientOracle indexed oldPriceOracle, ResilientOracle indexed priceOracle);
|
|
139
|
+
|
|
140
|
+
/// @notice Emitted when destination address is updated
|
|
141
|
+
event DestinationAddressUpdated(address indexed oldDestinationAddress, address indexed destinationAddress);
|
|
142
|
+
|
|
143
|
+
/// @notice Emitted when converterNetwork address is updated
|
|
144
|
+
event ConverterNetworkAddressUpdated(address indexed oldConverterNetwork, address indexed converterNetwork);
|
|
145
|
+
|
|
146
|
+
/// @notice Emitted when exact amount of tokens are converted for tokens
|
|
147
|
+
event ConvertedExactTokens(
|
|
148
|
+
address indexed sender,
|
|
149
|
+
address indexed receiver,
|
|
150
|
+
address tokenAddressIn,
|
|
151
|
+
address indexed tokenAddressOut,
|
|
152
|
+
uint256 amountIn,
|
|
153
|
+
uint256 amountOut
|
|
154
|
+
);
|
|
155
|
+
|
|
156
|
+
/// @notice Emitted when tokens are converted for exact amount of tokens
|
|
157
|
+
event ConvertedForExactTokens(
|
|
158
|
+
address indexed sender,
|
|
159
|
+
address indexed receiver,
|
|
160
|
+
address tokenAddressIn,
|
|
161
|
+
address indexed tokenAddressOut,
|
|
162
|
+
uint256 amountIn,
|
|
163
|
+
uint256 amountOut
|
|
164
|
+
);
|
|
165
|
+
|
|
166
|
+
/// @notice Emitted when exact amount of tokens are converted for tokens, for deflationary tokens
|
|
167
|
+
event ConvertedExactTokensSupportingFeeOnTransferTokens(
|
|
168
|
+
address indexed sender,
|
|
169
|
+
address indexed receiver,
|
|
170
|
+
address tokenAddressIn,
|
|
171
|
+
address indexed tokenAddressOut,
|
|
172
|
+
uint256 amountIn,
|
|
173
|
+
uint256 amountOut
|
|
174
|
+
);
|
|
175
|
+
|
|
176
|
+
/// @notice Emitted when tokens are converted for exact amount of tokens, for deflationary tokens
|
|
177
|
+
event ConvertedForExactTokensSupportingFeeOnTransferTokens(
|
|
178
|
+
address indexed sender,
|
|
179
|
+
address indexed receiver,
|
|
180
|
+
address tokenAddressIn,
|
|
181
|
+
address indexed tokenAddressOut,
|
|
182
|
+
uint256 amountIn,
|
|
183
|
+
uint256 amountOut
|
|
184
|
+
);
|
|
185
|
+
|
|
186
|
+
/// @notice Emitted when conversion is paused
|
|
187
|
+
event ConversionPaused(address indexed sender);
|
|
188
|
+
|
|
189
|
+
/// @notice Emitted when conversion is unpaused
|
|
190
|
+
event ConversionResumed(address indexed sender);
|
|
191
|
+
|
|
192
|
+
/// @notice Event emitted when tokens are swept
|
|
193
|
+
event SweepToken(address indexed token, address indexed to, uint256 amount);
|
|
194
|
+
|
|
195
|
+
/// @notice Emitted when minimum amount to convert is updated
|
|
196
|
+
event MinAmountToConvertUpdated(uint256 oldMinAmountToConvert, uint256 newMinAmountToConvert);
|
|
197
|
+
|
|
198
|
+
/// @notice Thrown when actualAmountOut does not match with amountOutMantissa for convertForExactTokens
|
|
199
|
+
error AmountOutMismatched();
|
|
200
|
+
|
|
201
|
+
/// @notice Thrown when actualAmountIn does not match with amountInMantissa for convertForExactTokens
|
|
202
|
+
error AmountInMismatched();
|
|
203
|
+
|
|
204
|
+
/// @notice Thrown when given input amount is zero
|
|
205
|
+
error InsufficientInputAmount();
|
|
206
|
+
|
|
207
|
+
/// @notice Thrown when given output amount is zero
|
|
208
|
+
error InsufficientOutputAmount();
|
|
209
|
+
|
|
210
|
+
/// @notice Thrown when conversion is disabled or config does not exist for given pair
|
|
211
|
+
error ConversionConfigNotEnabled();
|
|
212
|
+
|
|
213
|
+
/// @notice Thrown when conversion is enabled only for private conversions
|
|
214
|
+
error ConversionEnabledOnlyForPrivateConversions();
|
|
215
|
+
|
|
216
|
+
/// @notice Thrown when address(to) is same as tokenAddressIn or tokenAddressOut
|
|
217
|
+
error InvalidToAddress();
|
|
218
|
+
|
|
219
|
+
/// @notice Thrown when incentive is higher than the MAX_INCENTIVE
|
|
220
|
+
error IncentiveTooHigh(uint256 incentive, uint256 maxIncentive);
|
|
221
|
+
|
|
222
|
+
/// @notice Thrown when amountOut is lower than amountOutMin
|
|
223
|
+
error AmountOutLowerThanMinRequired(uint256 amountOutMantissa, uint256 amountOutMinMantissa);
|
|
224
|
+
|
|
225
|
+
/// @notice Thrown when amountIn is higher than amountInMax
|
|
226
|
+
error AmountInHigherThanMax(uint256 amountInMantissa, uint256 amountInMaxMantissa);
|
|
227
|
+
|
|
228
|
+
/// @notice Thrown when conversion is paused
|
|
229
|
+
error ConversionTokensPaused();
|
|
230
|
+
|
|
231
|
+
/// @notice Thrown when conversion is Active
|
|
232
|
+
error ConversionTokensActive();
|
|
233
|
+
|
|
234
|
+
/// @notice Thrown when tokenInAddress is same as tokeOutAdress OR tokeInAddress is not the base asset of the destination
|
|
235
|
+
error InvalidTokenConfigAddresses();
|
|
236
|
+
|
|
237
|
+
/// @notice Thrown when contract has less liquidity for tokenAddressOut than amountOutMantissa
|
|
238
|
+
error InsufficientPoolLiquidity();
|
|
239
|
+
|
|
240
|
+
/// @notice When address of the ConverterNetwork is not set or Zero address
|
|
241
|
+
error InvalidConverterNetwork();
|
|
242
|
+
|
|
243
|
+
/// @notice Thrown when trying to set non zero incentive for private conversion
|
|
244
|
+
error NonZeroIncentiveForPrivateConversion();
|
|
245
|
+
|
|
246
|
+
/// @notice Thrown when using convertForExactTokens deflationary tokens
|
|
247
|
+
error DeflationaryTokenNotSupported();
|
|
248
|
+
|
|
249
|
+
/// @notice Thrown when minimum amount to convert is zero
|
|
250
|
+
error InvalidMinimumAmountToConvert();
|
|
251
|
+
|
|
252
|
+
/// @notice Thrown when there is a mismatch in the length of input arrays
|
|
253
|
+
error InputLengthMisMatch();
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* @notice Modifier to ensure valid conversion parameters for a token conversion
|
|
257
|
+
* and check if conversion is paused or not
|
|
258
|
+
* @param to The recipient address for the converted tokens
|
|
259
|
+
* @param tokenAddressIn The input token address for the conversion
|
|
260
|
+
* @param tokenAddressOut The output token address for the conversion
|
|
261
|
+
*/
|
|
262
|
+
modifier validConversionParameters(
|
|
263
|
+
address to,
|
|
264
|
+
address tokenAddressIn,
|
|
265
|
+
address tokenAddressOut
|
|
266
|
+
) {
|
|
267
|
+
_checkConversionPaused();
|
|
268
|
+
ensureNonzeroAddress(to);
|
|
269
|
+
if (to == tokenAddressIn || to == tokenAddressOut) {
|
|
270
|
+
revert InvalidToAddress();
|
|
271
|
+
}
|
|
272
|
+
_;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
/// @notice Pause conversion of tokens
|
|
276
|
+
/// @custom:event Emits ConversionPaused on success
|
|
277
|
+
/// @custom:error ConversionTokensPaused thrown when conversion is already paused
|
|
278
|
+
/// @custom:access Restricted by ACM
|
|
279
|
+
function pauseConversion() external {
|
|
280
|
+
_checkAccessAllowed("pauseConversion()");
|
|
281
|
+
_checkConversionPaused();
|
|
282
|
+
conversionPaused = true;
|
|
283
|
+
emit ConversionPaused(msg.sender);
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
/// @notice Resume conversion of tokens.
|
|
287
|
+
/// @custom:event Emits ConversionResumed on success
|
|
288
|
+
/// @custom:error ConversionTokensActive thrown when conversion is already active
|
|
289
|
+
/// @custom:access Restricted by ACM
|
|
290
|
+
function resumeConversion() external {
|
|
291
|
+
_checkAccessAllowed("resumeConversion()");
|
|
292
|
+
if (!conversionPaused) {
|
|
293
|
+
revert ConversionTokensActive();
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
conversionPaused = false;
|
|
297
|
+
emit ConversionResumed(msg.sender);
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
/// @notice Sets a new price oracle
|
|
301
|
+
/// @param priceOracle_ Address of the new price oracle to set
|
|
302
|
+
/// @custom:access Only Governance
|
|
303
|
+
function setPriceOracle(ResilientOracle priceOracle_) external onlyOwner {
|
|
304
|
+
_setPriceOracle(priceOracle_);
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
/// @notice Sets a new destination address
|
|
308
|
+
/// @param destinationAddress_ The new destination address to be set
|
|
309
|
+
/// @custom:access Only Governance
|
|
310
|
+
function setDestination(address destinationAddress_) external onlyOwner {
|
|
311
|
+
_setDestination(destinationAddress_);
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
/// @notice Sets a converter network contract address
|
|
315
|
+
/// @param converterNetwork_ The converterNetwork address to be set
|
|
316
|
+
/// @custom:access Only Governance
|
|
317
|
+
function setConverterNetwork(IConverterNetwork converterNetwork_) external onlyOwner {
|
|
318
|
+
_setConverterNetwork(converterNetwork_);
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
/// @notice Min amount to convert setter
|
|
322
|
+
/// @param minAmountToConvert_ Min amount to convert
|
|
323
|
+
/// @custom:access Only Governance
|
|
324
|
+
function setMinAmountToConvert(uint256 minAmountToConvert_) external {
|
|
325
|
+
_checkAccessAllowed("setMinAmountToConvert(uint256)");
|
|
326
|
+
_setMinAmountToConvert(minAmountToConvert_);
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
/// @notice Batch sets the conversion configurations
|
|
330
|
+
/// @param tokenAddressIn Address of tokenIn
|
|
331
|
+
/// @param tokenAddressesOut Array of addresses of tokenOut
|
|
332
|
+
/// @param conversionConfigs Array of conversionConfig config details to update
|
|
333
|
+
/// @custom:error InputLengthMisMatch is thrown when tokenAddressesOut and conversionConfigs array length mismatches
|
|
334
|
+
function setConversionConfigs(
|
|
335
|
+
address tokenAddressIn,
|
|
336
|
+
address[] calldata tokenAddressesOut,
|
|
337
|
+
ConversionConfig[] calldata conversionConfigs
|
|
338
|
+
) external {
|
|
339
|
+
uint256 tokenOutArrayLength = tokenAddressesOut.length;
|
|
340
|
+
if (tokenOutArrayLength != conversionConfigs.length) revert InputLengthMisMatch();
|
|
341
|
+
|
|
342
|
+
for (uint256 i; i < tokenOutArrayLength; ) {
|
|
343
|
+
setConversionConfig(tokenAddressIn, tokenAddressesOut[i], conversionConfigs[i]);
|
|
344
|
+
unchecked {
|
|
345
|
+
++i;
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
/// @notice Converts exact amount of tokenAddressIn for tokenAddressOut if there is enough tokens held by the contract
|
|
351
|
+
/// @dev Method does not support deflationary tokens transfer
|
|
352
|
+
/// @param amountInMantissa Amount of tokenAddressIn
|
|
353
|
+
/// @param amountOutMinMantissa Min amount of tokenAddressOut required as output
|
|
354
|
+
/// @param tokenAddressIn Address of the token to convert
|
|
355
|
+
/// @param tokenAddressOut Address of the token to get after conversion
|
|
356
|
+
/// @param to Address of the tokenAddressOut receiver
|
|
357
|
+
/// @return actualAmountIn Actual amount transferred to destination
|
|
358
|
+
/// @return actualAmountOut Actual amount transferred to user
|
|
359
|
+
/// @custom:event Emits ConvertedExactTokens event on success
|
|
360
|
+
/// @custom:error ZeroAddressNotAllowed is thrown when to address is zero
|
|
361
|
+
/// @custom:error InvalidToAddress error is thrown when address(to) is same as tokenAddressIn or tokenAddressOut
|
|
362
|
+
/// @custom:error AmountOutLowerThanMinRequired error is thrown when amount of output tokenAddressOut is less than amountOutMinMantissa
|
|
363
|
+
/// @custom:error AmountInMismatched error is thrown when amount of output tokenAddressOut is less than amountOutMinMantissa
|
|
364
|
+
function convertExactTokens(
|
|
365
|
+
uint256 amountInMantissa,
|
|
366
|
+
uint256 amountOutMinMantissa,
|
|
367
|
+
address tokenAddressIn,
|
|
368
|
+
address tokenAddressOut,
|
|
369
|
+
address to
|
|
370
|
+
)
|
|
371
|
+
external
|
|
372
|
+
validConversionParameters(to, tokenAddressIn, tokenAddressOut)
|
|
373
|
+
nonReentrant
|
|
374
|
+
returns (uint256 actualAmountIn, uint256 actualAmountOut)
|
|
375
|
+
{
|
|
376
|
+
(actualAmountIn, actualAmountOut) = _convertExactTokens(
|
|
377
|
+
amountInMantissa,
|
|
378
|
+
amountOutMinMantissa,
|
|
379
|
+
tokenAddressIn,
|
|
380
|
+
tokenAddressOut,
|
|
381
|
+
to
|
|
382
|
+
);
|
|
383
|
+
|
|
384
|
+
if (actualAmountIn != amountInMantissa) {
|
|
385
|
+
revert AmountInMismatched();
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
_postConversionHook(tokenAddressIn, tokenAddressOut, actualAmountIn, actualAmountOut);
|
|
389
|
+
emit ConvertedExactTokens(msg.sender, to, tokenAddressIn, tokenAddressOut, actualAmountIn, actualAmountOut);
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
/// @notice Converts tokens for tokenAddressIn for exact amount of tokenAddressOut if there is enough tokens held by the contract,
|
|
393
|
+
/// otherwise the amount is adjusted
|
|
394
|
+
/// @dev Method does not support deflationary tokens transfer
|
|
395
|
+
/// @param amountInMaxMantissa Max amount of tokenAddressIn
|
|
396
|
+
/// @param amountOutMantissa Amount of tokenAddressOut required as output
|
|
397
|
+
/// @param tokenAddressIn Address of the token to convert
|
|
398
|
+
/// @param tokenAddressOut Address of the token to get after conversion
|
|
399
|
+
/// @param to Address of the tokenAddressOut receiver
|
|
400
|
+
/// @return actualAmountIn Actual amount transferred to destination
|
|
401
|
+
/// @return actualAmountOut Actual amount transferred to user
|
|
402
|
+
/// @custom:event Emits ConvertedForExactTokens event on success
|
|
403
|
+
/// @custom:error ZeroAddressNotAllowed is thrown when to address is zero
|
|
404
|
+
/// @custom:error InvalidToAddress error is thrown when address(to) is same as tokenAddressIn or tokenAddressOut
|
|
405
|
+
/// @custom:error AmountInHigherThanMax error is thrown when amount of tokenAddressIn is higher than amountInMaxMantissa
|
|
406
|
+
/// @custom:error AmountOutMismatched error is thrown when actualAmountOut is does not match amountOutMantissa
|
|
407
|
+
function convertForExactTokens(
|
|
408
|
+
uint256 amountInMaxMantissa,
|
|
409
|
+
uint256 amountOutMantissa,
|
|
410
|
+
address tokenAddressIn,
|
|
411
|
+
address tokenAddressOut,
|
|
412
|
+
address to
|
|
413
|
+
)
|
|
414
|
+
external
|
|
415
|
+
validConversionParameters(to, tokenAddressIn, tokenAddressOut)
|
|
416
|
+
nonReentrant
|
|
417
|
+
returns (uint256 actualAmountIn, uint256 actualAmountOut)
|
|
418
|
+
{
|
|
419
|
+
(actualAmountIn, actualAmountOut) = _convertForExactTokens(
|
|
420
|
+
amountInMaxMantissa,
|
|
421
|
+
amountOutMantissa,
|
|
422
|
+
tokenAddressIn,
|
|
423
|
+
tokenAddressOut,
|
|
424
|
+
to
|
|
425
|
+
);
|
|
426
|
+
|
|
427
|
+
if (actualAmountOut != amountOutMantissa) {
|
|
428
|
+
revert AmountOutMismatched();
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
_postConversionHook(tokenAddressIn, tokenAddressOut, actualAmountIn, actualAmountOut);
|
|
432
|
+
emit ConvertedForExactTokens(msg.sender, to, tokenAddressIn, tokenAddressOut, actualAmountIn, actualAmountOut);
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
/// @notice Converts exact amount of tokenAddressIn for tokenAddressOut if there is enough tokens held by the contract
|
|
436
|
+
/// @param amountInMantissa Amount of tokenAddressIn
|
|
437
|
+
/// @param amountOutMinMantissa Min amount of tokenAddressOut required as output
|
|
438
|
+
/// @param tokenAddressIn Address of the token to convert
|
|
439
|
+
/// @param tokenAddressOut Address of the token to get after conversion
|
|
440
|
+
/// @param to Address of the tokenAddressOut receiver
|
|
441
|
+
/// @return actualAmountIn Actual amount transferred to destination
|
|
442
|
+
/// @return actualAmountOut Actual amount transferred to user
|
|
443
|
+
/// @custom:event Emits ConvertedExactTokensSupportingFeeOnTransferTokens event on success
|
|
444
|
+
/// @custom:error ZeroAddressNotAllowed is thrown when to address is zero
|
|
445
|
+
/// @custom:error InvalidToAddress error is thrown when address(to) is same as tokenAddressIn or tokenAddressOut
|
|
446
|
+
/// @custom:error AmountOutLowerThanMinRequired error is thrown when amount of output tokenAddressOut is less than amountOutMinMantissa
|
|
447
|
+
function convertExactTokensSupportingFeeOnTransferTokens(
|
|
448
|
+
uint256 amountInMantissa,
|
|
449
|
+
uint256 amountOutMinMantissa,
|
|
450
|
+
address tokenAddressIn,
|
|
451
|
+
address tokenAddressOut,
|
|
452
|
+
address to
|
|
453
|
+
)
|
|
454
|
+
external
|
|
455
|
+
validConversionParameters(to, tokenAddressIn, tokenAddressOut)
|
|
456
|
+
nonReentrant
|
|
457
|
+
returns (uint256 actualAmountIn, uint256 actualAmountOut)
|
|
458
|
+
{
|
|
459
|
+
(actualAmountIn, actualAmountOut) = _convertExactTokens(
|
|
460
|
+
amountInMantissa,
|
|
461
|
+
amountOutMinMantissa,
|
|
462
|
+
tokenAddressIn,
|
|
463
|
+
tokenAddressOut,
|
|
464
|
+
to
|
|
465
|
+
);
|
|
466
|
+
|
|
467
|
+
_postConversionHook(tokenAddressIn, tokenAddressOut, actualAmountIn, actualAmountOut);
|
|
468
|
+
emit ConvertedExactTokensSupportingFeeOnTransferTokens(
|
|
469
|
+
msg.sender,
|
|
470
|
+
to,
|
|
471
|
+
tokenAddressIn,
|
|
472
|
+
tokenAddressOut,
|
|
473
|
+
actualAmountIn,
|
|
474
|
+
actualAmountOut
|
|
475
|
+
);
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
/// @notice Converts tokens for tokenAddressIn for amount of tokenAddressOut calculated on the basis of amount of
|
|
479
|
+
/// tokenAddressIn received by the contract, if there is enough tokens held by the contract, otherwise the amount is adjusted.
|
|
480
|
+
/// The user will be responsible for bearing any fees associated with token transfers, whether pulling in or pushing out tokens
|
|
481
|
+
/// @param amountInMaxMantissa Max amount of tokenAddressIn
|
|
482
|
+
/// @param amountOutMantissa Amount of tokenAddressOut required as output
|
|
483
|
+
/// @param tokenAddressIn Address of the token to convert
|
|
484
|
+
/// @param tokenAddressOut Address of the token to get after conversion
|
|
485
|
+
/// @param to Address of the tokenAddressOut receiver
|
|
486
|
+
/// @return actualAmountIn Actual amount transferred to destination
|
|
487
|
+
/// @return actualAmountOut Actual amount transferred to user
|
|
488
|
+
/// @custom:event Emits ConvertedForExactTokensSupportingFeeOnTransferTokens event on success
|
|
489
|
+
/// @custom:error ZeroAddressNotAllowed is thrown when to address is zero
|
|
490
|
+
/// @custom:error InvalidToAddress error is thrown when address(to) is same as tokenAddressIn or tokenAddressOut
|
|
491
|
+
/// @custom:error AmountInHigherThanMax error is thrown when amount of tokenAddressIn is higher than amountInMaxMantissa
|
|
492
|
+
function convertForExactTokensSupportingFeeOnTransferTokens(
|
|
493
|
+
uint256 amountInMaxMantissa,
|
|
494
|
+
uint256 amountOutMantissa,
|
|
495
|
+
address tokenAddressIn,
|
|
496
|
+
address tokenAddressOut,
|
|
497
|
+
address to
|
|
498
|
+
)
|
|
499
|
+
external
|
|
500
|
+
validConversionParameters(to, tokenAddressIn, tokenAddressOut)
|
|
501
|
+
nonReentrant
|
|
502
|
+
returns (uint256 actualAmountIn, uint256 actualAmountOut)
|
|
503
|
+
{
|
|
504
|
+
(actualAmountIn, actualAmountOut) = _convertForExactTokensSupportingFeeOnTransferTokens(
|
|
505
|
+
amountInMaxMantissa,
|
|
506
|
+
amountOutMantissa,
|
|
507
|
+
tokenAddressIn,
|
|
508
|
+
tokenAddressOut,
|
|
509
|
+
to
|
|
510
|
+
);
|
|
511
|
+
|
|
512
|
+
_postConversionHook(tokenAddressIn, tokenAddressOut, actualAmountIn, actualAmountOut);
|
|
513
|
+
emit ConvertedForExactTokensSupportingFeeOnTransferTokens(
|
|
514
|
+
msg.sender,
|
|
515
|
+
to,
|
|
516
|
+
tokenAddressIn,
|
|
517
|
+
tokenAddressOut,
|
|
518
|
+
actualAmountIn,
|
|
519
|
+
actualAmountOut
|
|
520
|
+
);
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
/// @notice To sweep ERC20 tokens and transfer them to user(to address)
|
|
524
|
+
/// @param tokenAddress The address of the ERC-20 token to sweep
|
|
525
|
+
/// @param to The address to which tokens will be transferred
|
|
526
|
+
/// @param amount The amount to transfer
|
|
527
|
+
/// @custom:event Emits SweepToken event on success
|
|
528
|
+
/// @custom:error ZeroAddressNotAllowed is thrown when tokenAddress/to address is zero
|
|
529
|
+
/// @custom:access Only Governance
|
|
530
|
+
function sweepToken(
|
|
531
|
+
address tokenAddress,
|
|
532
|
+
address to,
|
|
533
|
+
uint256 amount
|
|
534
|
+
) external onlyOwner nonReentrant {
|
|
535
|
+
ensureNonzeroAddress(tokenAddress);
|
|
536
|
+
ensureNonzeroAddress(to);
|
|
537
|
+
ensureNonzeroValue(amount);
|
|
538
|
+
|
|
539
|
+
IERC20Upgradeable token = IERC20Upgradeable(tokenAddress);
|
|
540
|
+
preSweepToken(tokenAddress, amount);
|
|
541
|
+
token.safeTransfer(to, amount);
|
|
542
|
+
|
|
543
|
+
emit SweepToken(tokenAddress, to, amount);
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
/// @notice To get the amount of tokenAddressOut tokens sender could receive on providing amountInMantissa tokens of tokenAddressIn.
|
|
547
|
+
/// This function does not account for potential token transfer fees(in case of deflationary tokens)
|
|
548
|
+
/// @dev This function retrieves values without altering token prices
|
|
549
|
+
/// @param amountInMantissa Amount of tokenAddressIn
|
|
550
|
+
/// @param tokenAddressIn Address of the token to convert
|
|
551
|
+
/// @param tokenAddressOut Address of the token to get after conversion
|
|
552
|
+
/// @return amountConvertedMantissa Amount of tokenAddressIn should be transferred after conversion
|
|
553
|
+
/// @return amountOutMantissa Amount of the tokenAddressOut sender should receive after conversion
|
|
554
|
+
/// @custom:error InsufficientInputAmount error is thrown when given input amount is zero
|
|
555
|
+
/// @custom:error ConversionConfigNotEnabled is thrown when conversion is disabled or config does not exist for given pair
|
|
556
|
+
/// @custom:error ConversionEnabledOnlyForPrivateConversions is thrown when conversion is only enabled for private conversion
|
|
557
|
+
function getAmountOut(
|
|
558
|
+
uint256 amountInMantissa,
|
|
559
|
+
address tokenAddressIn,
|
|
560
|
+
address tokenAddressOut
|
|
561
|
+
) external view returns (uint256 amountConvertedMantissa, uint256 amountOutMantissa) {
|
|
562
|
+
if (
|
|
563
|
+
conversionConfigurations[tokenAddressIn][tokenAddressOut].conversionAccess ==
|
|
564
|
+
ConversionAccessibility.ONLY_FOR_CONVERTERS
|
|
565
|
+
) {
|
|
566
|
+
revert ConversionEnabledOnlyForPrivateConversions();
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
amountConvertedMantissa = amountInMantissa;
|
|
570
|
+
uint256 tokenInToOutConversion;
|
|
571
|
+
(amountOutMantissa, tokenInToOutConversion) = _getAmountOut(amountInMantissa, tokenAddressIn, tokenAddressOut);
|
|
572
|
+
|
|
573
|
+
uint256 maxTokenOutReserve = balanceOf(tokenAddressOut);
|
|
574
|
+
|
|
575
|
+
/// If contract has less liquidity for tokenAddressOut than amountOutMantissa
|
|
576
|
+
if (maxTokenOutReserve < amountOutMantissa) {
|
|
577
|
+
amountConvertedMantissa =
|
|
578
|
+
((maxTokenOutReserve * EXP_SCALE) + tokenInToOutConversion - 1) /
|
|
579
|
+
tokenInToOutConversion; //round-up
|
|
580
|
+
amountOutMantissa = maxTokenOutReserve;
|
|
581
|
+
}
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
/// @notice To get the amount of tokenAddressIn tokens sender would send on receiving amountOutMantissa tokens of tokenAddressOut.
|
|
585
|
+
/// This function does not account for potential token transfer fees(in case of deflationary tokens)
|
|
586
|
+
/// @dev This function retrieves values without altering token prices
|
|
587
|
+
/// @param amountOutMantissa Amount of tokenAddressOut user wants to receive
|
|
588
|
+
/// @param tokenAddressIn Address of the token to convert
|
|
589
|
+
/// @param tokenAddressOut Address of the token to get after conversion
|
|
590
|
+
/// @return amountConvertedMantissa Amount of tokenAddressOut should be transferred after conversion
|
|
591
|
+
/// @return amountInMantissa Amount of the tokenAddressIn sender would send to contract before conversion
|
|
592
|
+
/// @custom:error InsufficientInputAmount error is thrown when given input amount is zero
|
|
593
|
+
/// @custom:error ConversionConfigNotEnabled is thrown when conversion is disabled or config does not exist for given pair
|
|
594
|
+
/// @custom:error ConversionEnabledOnlyForPrivateConversions is thrown when conversion is only enabled for private conversion
|
|
595
|
+
function getAmountIn(
|
|
596
|
+
uint256 amountOutMantissa,
|
|
597
|
+
address tokenAddressIn,
|
|
598
|
+
address tokenAddressOut
|
|
599
|
+
) external view returns (uint256 amountConvertedMantissa, uint256 amountInMantissa) {
|
|
600
|
+
if (
|
|
601
|
+
conversionConfigurations[tokenAddressIn][tokenAddressOut].conversionAccess ==
|
|
602
|
+
ConversionAccessibility.ONLY_FOR_CONVERTERS
|
|
603
|
+
) {
|
|
604
|
+
revert ConversionEnabledOnlyForPrivateConversions();
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
uint256 maxTokenOutReserve = balanceOf(tokenAddressOut);
|
|
608
|
+
|
|
609
|
+
/// If contract has less liquidity for tokenAddressOut than amountOutMantissa
|
|
610
|
+
if (maxTokenOutReserve < amountOutMantissa) {
|
|
611
|
+
amountOutMantissa = maxTokenOutReserve;
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
amountConvertedMantissa = amountOutMantissa;
|
|
615
|
+
(amountInMantissa, ) = _getAmountIn(amountOutMantissa, tokenAddressIn, tokenAddressOut);
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
/// @notice To get the amount of tokenAddressOut tokens sender could receive on providing amountInMantissa tokens of tokenAddressIn
|
|
619
|
+
/// @param amountInMantissa Amount of tokenAddressIn
|
|
620
|
+
/// @param tokenAddressIn Address of the token to convert
|
|
621
|
+
/// @param tokenAddressOut Address of the token to get after conversion
|
|
622
|
+
/// @return amountConvertedMantissa Amount of tokenAddressIn should be transferred after conversion
|
|
623
|
+
/// @return amountOutMantissa Amount of the tokenAddressOut sender should receive after conversion
|
|
624
|
+
/// @custom:error InsufficientInputAmount error is thrown when given input amount is zero
|
|
625
|
+
/// @custom:error ConversionConfigNotEnabled is thrown when conversion is disabled or config does not exist for given pair
|
|
626
|
+
function getUpdatedAmountOut(
|
|
627
|
+
uint256 amountInMantissa,
|
|
628
|
+
address tokenAddressIn,
|
|
629
|
+
address tokenAddressOut
|
|
630
|
+
) public returns (uint256 amountConvertedMantissa, uint256 amountOutMantissa) {
|
|
631
|
+
priceOracle.updateAssetPrice(tokenAddressIn);
|
|
632
|
+
priceOracle.updateAssetPrice(tokenAddressOut);
|
|
633
|
+
|
|
634
|
+
(amountOutMantissa, ) = _getAmountOut(amountInMantissa, tokenAddressIn, tokenAddressOut);
|
|
635
|
+
amountConvertedMantissa = amountInMantissa;
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
/// @notice To get the amount of tokenAddressIn tokens sender would send on receiving amountOutMantissa tokens of tokenAddressOut
|
|
639
|
+
/// @param amountOutMantissa Amount of tokenAddressOut user wants to receive
|
|
640
|
+
/// @param tokenAddressIn Address of the token to convert
|
|
641
|
+
/// @param tokenAddressOut Address of the token to get after conversion
|
|
642
|
+
/// @return amountConvertedMantissa Amount of tokenAddressOut should be transferred after conversion
|
|
643
|
+
/// @return amountInMantissa Amount of the tokenAddressIn sender would send to contract before conversion
|
|
644
|
+
/// @custom:error InsufficientInputAmount error is thrown when given input amount is zero
|
|
645
|
+
/// @custom:error ConversionConfigNotEnabled is thrown when conversion is disabled or config does not exist for given pair
|
|
646
|
+
function getUpdatedAmountIn(
|
|
647
|
+
uint256 amountOutMantissa,
|
|
648
|
+
address tokenAddressIn,
|
|
649
|
+
address tokenAddressOut
|
|
650
|
+
) public returns (uint256 amountConvertedMantissa, uint256 amountInMantissa) {
|
|
651
|
+
priceOracle.updateAssetPrice(tokenAddressIn);
|
|
652
|
+
priceOracle.updateAssetPrice(tokenAddressOut);
|
|
653
|
+
|
|
654
|
+
(amountInMantissa, ) = _getAmountIn(amountOutMantissa, tokenAddressIn, tokenAddressOut);
|
|
655
|
+
amountConvertedMantissa = amountOutMantissa;
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
/// @notice This method updated the states of this contract after getting funds from PSR
|
|
659
|
+
/// after settling the amount(if any) through privateConversion between converters
|
|
660
|
+
/// @dev This function is called by protocolShareReserve
|
|
661
|
+
/// @dev call _updateAssetsState to update the states related to the comptroller and asset transfer to the specific converter then
|
|
662
|
+
/// it calls the _privateConversion which will convert the asset into destination's base asset and transfer it to destination address
|
|
663
|
+
/// @param comptroller Comptroller address (pool)
|
|
664
|
+
/// @param asset Asset address
|
|
665
|
+
function updateAssetsState(address comptroller, address asset) public nonReentrant {
|
|
666
|
+
uint256 balanceDiff = _updateAssetsState(comptroller, asset);
|
|
667
|
+
if (balanceDiff > 0) {
|
|
668
|
+
_privateConversion(comptroller, asset, balanceDiff);
|
|
669
|
+
}
|
|
670
|
+
}
|
|
671
|
+
|
|
672
|
+
/// @notice Set the configuration for new or existing conversion pair
|
|
673
|
+
/// @param tokenAddressIn Address of tokenIn
|
|
674
|
+
/// @param tokenAddressOut Address of tokenOut
|
|
675
|
+
/// @param conversionConfig ConversionConfig config details to update
|
|
676
|
+
/// @custom:event Emits ConversionConfigUpdated event on success
|
|
677
|
+
/// @custom:error Unauthorized error is thrown when the call is not authorized by AccessControlManager
|
|
678
|
+
/// @custom:error ZeroAddressNotAllowed is thrown when pool registry address is zero
|
|
679
|
+
/// @custom:error NonZeroIncentiveForPrivateConversion is thrown when incentive is non zero for private conversion
|
|
680
|
+
/// @custom:access Controlled by AccessControlManager
|
|
681
|
+
function setConversionConfig(
|
|
682
|
+
address tokenAddressIn,
|
|
683
|
+
address tokenAddressOut,
|
|
684
|
+
ConversionConfig calldata conversionConfig
|
|
685
|
+
) public {
|
|
686
|
+
_checkAccessAllowed("setConversionConfig(address,address,ConversionConfig)");
|
|
687
|
+
ensureNonzeroAddress(tokenAddressIn);
|
|
688
|
+
ensureNonzeroAddress(tokenAddressOut);
|
|
689
|
+
|
|
690
|
+
if (conversionConfig.incentive > MAX_INCENTIVE) {
|
|
691
|
+
revert IncentiveTooHigh(conversionConfig.incentive, MAX_INCENTIVE);
|
|
692
|
+
}
|
|
693
|
+
|
|
694
|
+
if (
|
|
695
|
+
(tokenAddressIn == tokenAddressOut) ||
|
|
696
|
+
(tokenAddressIn != _getDestinationBaseAsset()) ||
|
|
697
|
+
conversionConfigurations[tokenAddressOut][tokenAddressIn].conversionAccess != ConversionAccessibility.NONE
|
|
698
|
+
) {
|
|
699
|
+
revert InvalidTokenConfigAddresses();
|
|
700
|
+
}
|
|
701
|
+
|
|
702
|
+
if (
|
|
703
|
+
(conversionConfig.conversionAccess == ConversionAccessibility.ONLY_FOR_CONVERTERS) &&
|
|
704
|
+
conversionConfig.incentive != 0
|
|
705
|
+
) {
|
|
706
|
+
revert NonZeroIncentiveForPrivateConversion();
|
|
707
|
+
}
|
|
708
|
+
|
|
709
|
+
if (
|
|
710
|
+
((conversionConfig.conversionAccess == ConversionAccessibility.ONLY_FOR_CONVERTERS) ||
|
|
711
|
+
(conversionConfig.conversionAccess == ConversionAccessibility.ALL)) &&
|
|
712
|
+
(address(converterNetwork) == address(0))
|
|
713
|
+
) {
|
|
714
|
+
revert InvalidConverterNetwork();
|
|
715
|
+
}
|
|
716
|
+
|
|
717
|
+
ConversionConfig storage configuration = conversionConfigurations[tokenAddressIn][tokenAddressOut];
|
|
718
|
+
|
|
719
|
+
emit ConversionConfigUpdated(
|
|
720
|
+
tokenAddressIn,
|
|
721
|
+
tokenAddressOut,
|
|
722
|
+
configuration.incentive,
|
|
723
|
+
conversionConfig.incentive,
|
|
724
|
+
configuration.conversionAccess,
|
|
725
|
+
conversionConfig.conversionAccess
|
|
726
|
+
);
|
|
727
|
+
|
|
728
|
+
if (conversionConfig.conversionAccess == ConversionAccessibility.NONE) {
|
|
729
|
+
delete conversionConfigurations[tokenAddressIn][tokenAddressOut];
|
|
730
|
+
} else {
|
|
731
|
+
configuration.incentive = conversionConfig.incentive;
|
|
732
|
+
configuration.conversionAccess = conversionConfig.conversionAccess;
|
|
733
|
+
}
|
|
734
|
+
}
|
|
735
|
+
|
|
736
|
+
/// @notice Get the balance for specific token
|
|
737
|
+
/// @param token Address of the token
|
|
738
|
+
/// @return tokenBalance Balance of the token the contract has
|
|
739
|
+
function balanceOf(address token) public view virtual returns (uint256 tokenBalance);
|
|
740
|
+
|
|
741
|
+
/// @dev Operations to perform before sweeping tokens
|
|
742
|
+
/// @param token Address of the token
|
|
743
|
+
/// @param amount Amount transferred to address(to)
|
|
744
|
+
function preSweepToken(address token, uint256 amount) internal virtual {}
|
|
745
|
+
|
|
746
|
+
/// @dev Converts exact amount of tokenAddressIn for tokenAddressOut
|
|
747
|
+
/// @param amountInMantissa Amount of tokenAddressIn
|
|
748
|
+
/// @param amountOutMinMantissa Min amount of tokenAddressOut required as output
|
|
749
|
+
/// @param tokenAddressIn Address of the token to convert
|
|
750
|
+
/// @param tokenAddressOut Address of the token to get after conversion
|
|
751
|
+
/// @param to Address of the tokenAddressOut receiver
|
|
752
|
+
/// @return actualAmountIn Actual amount of tokenAddressIn transferred
|
|
753
|
+
/// @return amountOutMantissa Actual amount of tokenAddressOut transferred
|
|
754
|
+
/// @custom:error AmountOutLowerThanMinRequired error is thrown when amount of output tokenAddressOut is less than amountOutMinMantissa
|
|
755
|
+
function _convertExactTokens(
|
|
756
|
+
uint256 amountInMantissa,
|
|
757
|
+
uint256 amountOutMinMantissa,
|
|
758
|
+
address tokenAddressIn,
|
|
759
|
+
address tokenAddressOut,
|
|
760
|
+
address to
|
|
761
|
+
) internal returns (uint256 actualAmountIn, uint256 amountOutMantissa) {
|
|
762
|
+
_checkPrivateConversion(tokenAddressIn, tokenAddressOut);
|
|
763
|
+
actualAmountIn = _doTransferIn(tokenAddressIn, amountInMantissa);
|
|
764
|
+
|
|
765
|
+
(, amountOutMantissa) = getUpdatedAmountOut(actualAmountIn, tokenAddressIn, tokenAddressOut);
|
|
766
|
+
|
|
767
|
+
if (amountOutMantissa < amountOutMinMantissa) {
|
|
768
|
+
revert AmountOutLowerThanMinRequired(amountOutMantissa, amountOutMinMantissa);
|
|
769
|
+
}
|
|
770
|
+
|
|
771
|
+
_doTransferOut(tokenAddressOut, to, amountOutMantissa);
|
|
772
|
+
}
|
|
773
|
+
|
|
774
|
+
/// @dev Converts tokens for tokenAddressIn for exact amount of tokenAddressOut used for non deflationry tokens
|
|
775
|
+
/// it is called by convertForExactTokens function
|
|
776
|
+
/// @param amountInMaxMantissa Max amount of tokenAddressIn
|
|
777
|
+
/// @param amountOutMantissa Amount of tokenAddressOut required as output
|
|
778
|
+
/// @param tokenAddressIn Address of the token to convert
|
|
779
|
+
/// @param tokenAddressOut Address of the token to get after conversion
|
|
780
|
+
/// @param to Address of the tokenAddressOut receiver
|
|
781
|
+
/// @return actualAmountIn Actual amount of tokenAddressIn transferred
|
|
782
|
+
/// @return actualAmountOut Actual amount of tokenAddressOut transferred
|
|
783
|
+
/// @custom:error DeflationaryTokenNotSupported is thrown if tokenAddressIn is deflationary token
|
|
784
|
+
/// @custom:error AmountInHigherThanMax error is thrown when amount of tokenAddressIn is higher than amountInMaxMantissa
|
|
785
|
+
function _convertForExactTokens(
|
|
786
|
+
uint256 amountInMaxMantissa,
|
|
787
|
+
uint256 amountOutMantissa,
|
|
788
|
+
address tokenAddressIn,
|
|
789
|
+
address tokenAddressOut,
|
|
790
|
+
address to
|
|
791
|
+
) internal returns (uint256 actualAmountIn, uint256 actualAmountOut) {
|
|
792
|
+
_checkPrivateConversion(tokenAddressIn, tokenAddressOut);
|
|
793
|
+
(, uint256 amountInMantissa) = getUpdatedAmountIn(amountOutMantissa, tokenAddressIn, tokenAddressOut);
|
|
794
|
+
|
|
795
|
+
actualAmountIn = _doTransferIn(tokenAddressIn, amountInMantissa);
|
|
796
|
+
|
|
797
|
+
if (actualAmountIn != amountInMantissa) {
|
|
798
|
+
revert DeflationaryTokenNotSupported();
|
|
799
|
+
}
|
|
800
|
+
|
|
801
|
+
if (actualAmountIn > amountInMaxMantissa) {
|
|
802
|
+
revert AmountInHigherThanMax(amountInMantissa, amountInMaxMantissa);
|
|
803
|
+
}
|
|
804
|
+
|
|
805
|
+
_doTransferOut(tokenAddressOut, to, amountOutMantissa);
|
|
806
|
+
actualAmountOut = amountOutMantissa;
|
|
807
|
+
}
|
|
808
|
+
|
|
809
|
+
/// @dev Converts tokens for tokenAddressIn for the amount of tokenAddressOut used for deflationary tokens
|
|
810
|
+
/// it is called by convertForExactTokensSupportingFeeOnTransferTokens function
|
|
811
|
+
/// @param amountInMaxMantissa Max amount of tokenAddressIn
|
|
812
|
+
/// @param amountOutMantissa Amount of tokenAddressOut required as output
|
|
813
|
+
/// @param tokenAddressIn Address of the token to convert
|
|
814
|
+
/// @param tokenAddressOut Address of the token to get after conversion
|
|
815
|
+
/// @param to Address of the tokenAddressOut receiver
|
|
816
|
+
/// @return actualAmountIn Actual amount of tokenAddressIn transferred
|
|
817
|
+
/// @return actualAmountOut Actual amount of tokenAddressOut transferred
|
|
818
|
+
/// @custom:error AmountInHigherThanMax error is thrown when amount of tokenAddressIn is higher than amountInMaxMantissa
|
|
819
|
+
function _convertForExactTokensSupportingFeeOnTransferTokens(
|
|
820
|
+
uint256 amountInMaxMantissa,
|
|
821
|
+
uint256 amountOutMantissa,
|
|
822
|
+
address tokenAddressIn,
|
|
823
|
+
address tokenAddressOut,
|
|
824
|
+
address to
|
|
825
|
+
) internal returns (uint256 actualAmountIn, uint256 actualAmountOut) {
|
|
826
|
+
_checkPrivateConversion(tokenAddressIn, tokenAddressOut);
|
|
827
|
+
(, uint256 amountInMantissa) = getUpdatedAmountIn(amountOutMantissa, tokenAddressIn, tokenAddressOut);
|
|
828
|
+
|
|
829
|
+
if (amountInMantissa > amountInMaxMantissa) {
|
|
830
|
+
revert AmountInHigherThanMax(amountInMantissa, amountInMaxMantissa);
|
|
831
|
+
}
|
|
832
|
+
|
|
833
|
+
actualAmountIn = _doTransferIn(tokenAddressIn, amountInMantissa);
|
|
834
|
+
|
|
835
|
+
(, actualAmountOut) = getUpdatedAmountOut(actualAmountIn, tokenAddressIn, tokenAddressOut);
|
|
836
|
+
|
|
837
|
+
_doTransferOut(tokenAddressOut, to, actualAmountOut);
|
|
838
|
+
}
|
|
839
|
+
|
|
840
|
+
/// @dev return actualAmountOut from reserves for tokenAddressOut
|
|
841
|
+
/// @param tokenAddressOut Address of the token to get after conversion
|
|
842
|
+
/// @param to Address of the tokenAddressOut receiver
|
|
843
|
+
/// @param amountConvertedMantissa Amount of tokenAddressOut supposed to get transferred
|
|
844
|
+
/// @custom:error InsufficientPoolLiquidity If contract has less liquidity for tokenAddressOut than amountOutMantissa
|
|
845
|
+
function _doTransferOut(
|
|
846
|
+
address tokenAddressOut,
|
|
847
|
+
address to,
|
|
848
|
+
uint256 amountConvertedMantissa
|
|
849
|
+
) internal {
|
|
850
|
+
uint256 maxTokenOutReserve = balanceOf(tokenAddressOut);
|
|
851
|
+
|
|
852
|
+
/// If contract has less liquidity for tokenAddressOut than amountOutMantissa
|
|
853
|
+
if (maxTokenOutReserve < amountConvertedMantissa) {
|
|
854
|
+
revert InsufficientPoolLiquidity();
|
|
855
|
+
}
|
|
856
|
+
|
|
857
|
+
_preTransferHook(tokenAddressOut, amountConvertedMantissa);
|
|
858
|
+
|
|
859
|
+
IERC20Upgradeable tokenOut = IERC20Upgradeable(tokenAddressOut);
|
|
860
|
+
tokenOut.safeTransfer(to, amountConvertedMantissa);
|
|
861
|
+
}
|
|
862
|
+
|
|
863
|
+
/// @notice Transfer tokenAddressIn from user to destination
|
|
864
|
+
/// @param tokenAddressIn Address of the token to convert
|
|
865
|
+
/// @param amountInMantissa Amount of tokenAddressIn
|
|
866
|
+
/// @return actualAmountIn Actual amount transferred to destination
|
|
867
|
+
function _doTransferIn(address tokenAddressIn, uint256 amountInMantissa) internal returns (uint256 actualAmountIn) {
|
|
868
|
+
IERC20Upgradeable tokenIn = IERC20Upgradeable(tokenAddressIn);
|
|
869
|
+
uint256 balanceBeforeDestination = tokenIn.balanceOf(destinationAddress);
|
|
870
|
+
tokenIn.safeTransferFrom(msg.sender, destinationAddress, amountInMantissa);
|
|
871
|
+
uint256 balanceAfterDestination = tokenIn.balanceOf(destinationAddress);
|
|
872
|
+
actualAmountIn = balanceAfterDestination - balanceBeforeDestination;
|
|
873
|
+
}
|
|
874
|
+
|
|
875
|
+
/// @dev Sets a new price oracle
|
|
876
|
+
/// @param priceOracle_ Address of the new price oracle to set
|
|
877
|
+
/// @custom:event Emits PriceOracleUpdated event on success
|
|
878
|
+
/// @custom:error ZeroAddressNotAllowed is thrown when price oracle address is zero
|
|
879
|
+
function _setPriceOracle(ResilientOracle priceOracle_) internal {
|
|
880
|
+
ensureNonzeroAddress(address(priceOracle_));
|
|
881
|
+
emit PriceOracleUpdated(priceOracle, priceOracle_);
|
|
882
|
+
priceOracle = priceOracle_;
|
|
883
|
+
}
|
|
884
|
+
|
|
885
|
+
/// @dev Sets a new destination address
|
|
886
|
+
/// @param destinationAddress_ The new destination address to be set
|
|
887
|
+
/// @custom:event Emits DestinationAddressUpdated event on success
|
|
888
|
+
/// @custom:error ZeroAddressNotAllowed is thrown when destination address is zero
|
|
889
|
+
function _setDestination(address destinationAddress_) internal {
|
|
890
|
+
ensureNonzeroAddress(destinationAddress_);
|
|
891
|
+
emit DestinationAddressUpdated(destinationAddress, destinationAddress_);
|
|
892
|
+
destinationAddress = destinationAddress_;
|
|
893
|
+
}
|
|
894
|
+
|
|
895
|
+
/// @notice Sets a converter network contract address
|
|
896
|
+
/// @param converterNetwork_ The converterNetwork address to be set
|
|
897
|
+
/// @custom:event Emits ConverterNetworkAddressUpdated event on success
|
|
898
|
+
/// @custom:error ZeroAddressNotAllowed is thrown when address is zero
|
|
899
|
+
function _setConverterNetwork(IConverterNetwork converterNetwork_) internal {
|
|
900
|
+
ensureNonzeroAddress(address(converterNetwork_));
|
|
901
|
+
emit ConverterNetworkAddressUpdated(address(converterNetwork), address(converterNetwork_));
|
|
902
|
+
converterNetwork = converterNetwork_;
|
|
903
|
+
}
|
|
904
|
+
|
|
905
|
+
/// @notice Min amount to convert setter
|
|
906
|
+
/// @param minAmountToConvert_ Min amount to convert
|
|
907
|
+
/// @custom:event MinAmountToConvertUpdated is emitted in success
|
|
908
|
+
/// @custom:error ZeroValueNotAllowed is thrown if the provided value is 0
|
|
909
|
+
function _setMinAmountToConvert(uint256 minAmountToConvert_) internal {
|
|
910
|
+
ensureNonzeroValue(minAmountToConvert_);
|
|
911
|
+
emit MinAmountToConvertUpdated(minAmountToConvert, minAmountToConvert_);
|
|
912
|
+
minAmountToConvert = minAmountToConvert_;
|
|
913
|
+
}
|
|
914
|
+
|
|
915
|
+
/// @dev Hook to perform after converting tokens
|
|
916
|
+
/// @param tokenAddressIn Address of the token to convert
|
|
917
|
+
/// @param tokenAddressOut Address of the token to get after conversion
|
|
918
|
+
/// @param amountIn Amount of tokenIn converted
|
|
919
|
+
/// @param amountOut Amount of tokenOut converted
|
|
920
|
+
function _postConversionHook(
|
|
921
|
+
address tokenAddressIn,
|
|
922
|
+
address tokenAddressOut,
|
|
923
|
+
uint256 amountIn,
|
|
924
|
+
uint256 amountOut
|
|
925
|
+
) internal virtual {}
|
|
926
|
+
|
|
927
|
+
/// @param accessControlManager_ Access control manager contract address
|
|
928
|
+
/// @param priceOracle_ Resilient oracle address
|
|
929
|
+
/// @param destinationAddress_ Address at all incoming tokens will transferred to
|
|
930
|
+
/// @param minAmountToConvert_ minimum amount to convert
|
|
931
|
+
function __AbstractTokenConverter_init(
|
|
932
|
+
address accessControlManager_,
|
|
933
|
+
ResilientOracle priceOracle_,
|
|
934
|
+
address destinationAddress_,
|
|
935
|
+
uint256 minAmountToConvert_
|
|
936
|
+
) internal onlyInitializing {
|
|
937
|
+
__AccessControlled_init(accessControlManager_);
|
|
938
|
+
__ReentrancyGuard_init();
|
|
939
|
+
__AbstractTokenConverter_init_unchained(priceOracle_, destinationAddress_, minAmountToConvert_);
|
|
940
|
+
}
|
|
941
|
+
|
|
942
|
+
/// @param priceOracle_ Resilient oracle address
|
|
943
|
+
/// @param destinationAddress_ Address at all incoming tokens will transferred to
|
|
944
|
+
/// @param minAmountToConvert_ minimum amount to convert
|
|
945
|
+
function __AbstractTokenConverter_init_unchained(
|
|
946
|
+
ResilientOracle priceOracle_,
|
|
947
|
+
address destinationAddress_,
|
|
948
|
+
uint256 minAmountToConvert_
|
|
949
|
+
) internal onlyInitializing {
|
|
950
|
+
_setPriceOracle(priceOracle_);
|
|
951
|
+
_setDestination(destinationAddress_);
|
|
952
|
+
_setMinAmountToConvert(minAmountToConvert_);
|
|
953
|
+
conversionPaused = false;
|
|
954
|
+
}
|
|
955
|
+
|
|
956
|
+
/// @dev _updateAssetsState hook to update the states of reserves transferred for the specific comptroller
|
|
957
|
+
/// @param comptroller Comptroller address (pool)
|
|
958
|
+
/// @param asset Asset address
|
|
959
|
+
/// @return Amount of asset, for _privateConversion
|
|
960
|
+
function _updateAssetsState(address comptroller, address asset) internal virtual returns (uint256) {}
|
|
961
|
+
|
|
962
|
+
/// @dev This method is used to convert asset into base asset by converting them with other converters which supports the pair and transfer the funds to
|
|
963
|
+
/// destination contract as destination's base asset
|
|
964
|
+
/// @param comptroller Comptroller address (pool)
|
|
965
|
+
/// @param tokenAddressOut Address of the token transferred to converter, and through _privateConversion it will be converted into base asset
|
|
966
|
+
/// @param amountToConvert Amount of the tokenAddressOut transferred to converter
|
|
967
|
+
function _privateConversion(
|
|
968
|
+
address comptroller,
|
|
969
|
+
address tokenAddressOut,
|
|
970
|
+
uint256 amountToConvert
|
|
971
|
+
) internal {
|
|
972
|
+
address tokenAddressIn = _getDestinationBaseAsset();
|
|
973
|
+
address _destinationAddress = destinationAddress;
|
|
974
|
+
uint256 convertedTokenInBalance;
|
|
975
|
+
if (address(converterNetwork) != address(0)) {
|
|
976
|
+
(address[] memory converterAddresses, uint256[] memory converterBalances) = converterNetwork
|
|
977
|
+
.findTokenConvertersForConverters(tokenAddressOut, tokenAddressIn);
|
|
978
|
+
uint256 convertersLength = converterAddresses.length;
|
|
979
|
+
for (uint256 i; i < convertersLength; ) {
|
|
980
|
+
if (converterBalances[i] == 0) break;
|
|
981
|
+
(, uint256 amountIn) = IAbstractTokenConverter(converterAddresses[i]).getUpdatedAmountIn(
|
|
982
|
+
converterBalances[i],
|
|
983
|
+
tokenAddressOut,
|
|
984
|
+
tokenAddressIn
|
|
985
|
+
);
|
|
986
|
+
if (amountIn > amountToConvert) {
|
|
987
|
+
amountIn = amountToConvert;
|
|
988
|
+
}
|
|
989
|
+
|
|
990
|
+
if (!_validateMinAmountToConvert(amountIn, tokenAddressOut)) {
|
|
991
|
+
break;
|
|
992
|
+
}
|
|
993
|
+
|
|
994
|
+
uint256 balanceBefore = IERC20Upgradeable(tokenAddressIn).balanceOf(_destinationAddress);
|
|
995
|
+
|
|
996
|
+
IERC20Upgradeable(tokenAddressOut).approve(converterAddresses[i], amountIn);
|
|
997
|
+
IAbstractTokenConverter(converterAddresses[i]).convertExactTokens(
|
|
998
|
+
amountIn,
|
|
999
|
+
0,
|
|
1000
|
+
tokenAddressOut,
|
|
1001
|
+
tokenAddressIn,
|
|
1002
|
+
_destinationAddress
|
|
1003
|
+
);
|
|
1004
|
+
|
|
1005
|
+
uint256 balanceAfter = IERC20Upgradeable(tokenAddressIn).balanceOf(_destinationAddress);
|
|
1006
|
+
amountToConvert -= amountIn;
|
|
1007
|
+
convertedTokenInBalance += (balanceAfter - balanceBefore);
|
|
1008
|
+
|
|
1009
|
+
if (amountToConvert == 0) break;
|
|
1010
|
+
unchecked {
|
|
1011
|
+
++i;
|
|
1012
|
+
}
|
|
1013
|
+
}
|
|
1014
|
+
}
|
|
1015
|
+
|
|
1016
|
+
_postPrivateConversionHook(
|
|
1017
|
+
comptroller,
|
|
1018
|
+
tokenAddressIn,
|
|
1019
|
+
convertedTokenInBalance,
|
|
1020
|
+
tokenAddressOut,
|
|
1021
|
+
amountToConvert
|
|
1022
|
+
);
|
|
1023
|
+
}
|
|
1024
|
+
|
|
1025
|
+
/// @dev This hook is used to update states for the converter after the privateConversion
|
|
1026
|
+
/// @param comptroller Comptroller address (pool)
|
|
1027
|
+
/// @param tokenAddressIn Address of the destination's base asset
|
|
1028
|
+
/// @param convertedTokenInBalance Amount of the base asset received after the conversion
|
|
1029
|
+
/// @param tokenAddressOut Address of the asset transferred to other converter in exchange of base asset
|
|
1030
|
+
/// @param convertedTokenOutBalance Amount of tokenAddressOut transferred from this converter
|
|
1031
|
+
function _postPrivateConversionHook(
|
|
1032
|
+
address comptroller,
|
|
1033
|
+
address tokenAddressIn,
|
|
1034
|
+
uint256 convertedTokenInBalance,
|
|
1035
|
+
address tokenAddressOut,
|
|
1036
|
+
uint256 convertedTokenOutBalance
|
|
1037
|
+
) internal virtual {}
|
|
1038
|
+
|
|
1039
|
+
/// @notice This hook is used to update the state for asset reserves before transferring tokenOut to user
|
|
1040
|
+
/// @param tokenOutAddress Address of the asset to be transferred to the user
|
|
1041
|
+
/// @param amountOut Amount of tokenAddressOut transferred from this converter
|
|
1042
|
+
function _preTransferHook(address tokenOutAddress, uint256 amountOut) internal virtual {}
|
|
1043
|
+
|
|
1044
|
+
/// @dev Checks if amount to convert is greater than minimum amount to convert or not
|
|
1045
|
+
/// @param amountIn The amount to convert
|
|
1046
|
+
/// @param tokenAddress Address of the token
|
|
1047
|
+
/// @return isValid true if amount to convert is greater than minimum amount to convert
|
|
1048
|
+
function _validateMinAmountToConvert(uint256 amountIn, address tokenAddress) internal returns (bool isValid) {
|
|
1049
|
+
priceOracle.updateAssetPrice(tokenAddress);
|
|
1050
|
+
uint256 amountInInUsd = (priceOracle.getPrice(tokenAddress) * amountIn) / EXP_SCALE;
|
|
1051
|
+
|
|
1052
|
+
if (amountInInUsd >= minAmountToConvert) {
|
|
1053
|
+
isValid = true;
|
|
1054
|
+
}
|
|
1055
|
+
}
|
|
1056
|
+
|
|
1057
|
+
/// @notice To get the amount of tokenAddressOut tokens sender could receive on providing amountInMantissa tokens of tokenAddressIn
|
|
1058
|
+
/// @dev This function retrieves values without altering token prices.
|
|
1059
|
+
/// @param amountInMantissa Amount of tokenAddressIn
|
|
1060
|
+
/// @param tokenAddressIn Address of the token to convert
|
|
1061
|
+
/// @param tokenAddressOut Address of the token to get after conversion
|
|
1062
|
+
/// @return amountOutMantissa Amount of the tokenAddressOut sender should receive after conversion
|
|
1063
|
+
/// @return tokenInToOutConversion Ratio of tokenIn price and incentive for conversion with tokenOut price
|
|
1064
|
+
/// @custom:error InsufficientInputAmount error is thrown when given input amount is zero
|
|
1065
|
+
/// @custom:error ConversionConfigNotEnabled is thrown when conversion is disabled or config does not exist for given pair
|
|
1066
|
+
function _getAmountOut(
|
|
1067
|
+
uint256 amountInMantissa,
|
|
1068
|
+
address tokenAddressIn,
|
|
1069
|
+
address tokenAddressOut
|
|
1070
|
+
) internal view returns (uint256 amountOutMantissa, uint256 tokenInToOutConversion) {
|
|
1071
|
+
if (amountInMantissa == 0) {
|
|
1072
|
+
revert InsufficientInputAmount();
|
|
1073
|
+
}
|
|
1074
|
+
|
|
1075
|
+
ConversionConfig memory configuration = conversionConfigurations[tokenAddressIn][tokenAddressOut];
|
|
1076
|
+
|
|
1077
|
+
if (configuration.conversionAccess == ConversionAccessibility.NONE) {
|
|
1078
|
+
revert ConversionConfigNotEnabled();
|
|
1079
|
+
}
|
|
1080
|
+
|
|
1081
|
+
uint256 tokenInUnderlyingPrice = priceOracle.getPrice(tokenAddressIn);
|
|
1082
|
+
uint256 tokenOutUnderlyingPrice = priceOracle.getPrice(tokenAddressOut);
|
|
1083
|
+
|
|
1084
|
+
uint256 incentive = configuration.incentive;
|
|
1085
|
+
if (address(converterNetwork) != address(0) && (converterNetwork.isTokenConverter(msg.sender))) {
|
|
1086
|
+
incentive = 0;
|
|
1087
|
+
}
|
|
1088
|
+
|
|
1089
|
+
/// conversion rate after considering incentive(conversionWithIncentive)
|
|
1090
|
+
uint256 conversionWithIncentive = MANTISSA_ONE + incentive;
|
|
1091
|
+
|
|
1092
|
+
/// amount of tokenAddressOut after including incentive as amountOutMantissa will be greater than actual as it gets
|
|
1093
|
+
/// multiplied by conversionWithIncentive which will be >= 1
|
|
1094
|
+
amountOutMantissa =
|
|
1095
|
+
(amountInMantissa * tokenInUnderlyingPrice * conversionWithIncentive) /
|
|
1096
|
+
(tokenOutUnderlyingPrice * EXP_SCALE);
|
|
1097
|
+
|
|
1098
|
+
tokenInToOutConversion = (tokenInUnderlyingPrice * conversionWithIncentive) / tokenOutUnderlyingPrice;
|
|
1099
|
+
}
|
|
1100
|
+
|
|
1101
|
+
/// @dev To get the amount of tokenAddressIn tokens sender would send on receiving amountOutMantissa tokens of tokenAddressOut
|
|
1102
|
+
/// @dev This function retrieves values without altering token prices.
|
|
1103
|
+
/// @param amountOutMantissa Amount of tokenAddressOut user wants to receive
|
|
1104
|
+
/// @param tokenAddressIn Address of the token to convert
|
|
1105
|
+
/// @param tokenAddressOut Address of the token to get after conversion
|
|
1106
|
+
/// @return amountInMantissa Amount of the tokenAddressIn sender would send to contract before conversion
|
|
1107
|
+
/// @return tokenInToOutConversion Ratio of tokenIn price and incentive for conversion with tokenOut price
|
|
1108
|
+
/// @custom:error InsufficientInputAmount error is thrown when given input amount is zero
|
|
1109
|
+
/// @custom:error ConversionConfigNotEnabled is thrown when conversion is disabled or config does not exist for given pair
|
|
1110
|
+
function _getAmountIn(
|
|
1111
|
+
uint256 amountOutMantissa,
|
|
1112
|
+
address tokenAddressIn,
|
|
1113
|
+
address tokenAddressOut
|
|
1114
|
+
) internal view returns (uint256 amountInMantissa, uint256 tokenInToOutConversion) {
|
|
1115
|
+
if (amountOutMantissa == 0) {
|
|
1116
|
+
revert InsufficientOutputAmount();
|
|
1117
|
+
}
|
|
1118
|
+
|
|
1119
|
+
ConversionConfig memory configuration = conversionConfigurations[tokenAddressIn][tokenAddressOut];
|
|
1120
|
+
|
|
1121
|
+
if (configuration.conversionAccess == ConversionAccessibility.NONE) {
|
|
1122
|
+
revert ConversionConfigNotEnabled();
|
|
1123
|
+
}
|
|
1124
|
+
|
|
1125
|
+
uint256 tokenInUnderlyingPrice = priceOracle.getPrice(tokenAddressIn);
|
|
1126
|
+
uint256 tokenOutUnderlyingPrice = priceOracle.getPrice(tokenAddressOut);
|
|
1127
|
+
|
|
1128
|
+
uint256 incentive = configuration.incentive;
|
|
1129
|
+
if ((address(converterNetwork) != address(0)) && (converterNetwork.isTokenConverter(msg.sender))) {
|
|
1130
|
+
incentive = 0;
|
|
1131
|
+
}
|
|
1132
|
+
|
|
1133
|
+
/// conversion rate after considering incentive(conversionWithIncentive)
|
|
1134
|
+
uint256 conversionWithIncentive = MANTISSA_ONE + incentive;
|
|
1135
|
+
tokenInToOutConversion = (tokenInUnderlyingPrice * conversionWithIncentive) / tokenOutUnderlyingPrice;
|
|
1136
|
+
|
|
1137
|
+
/// amount of tokenAddressIn after considering incentive(i.e. amountInMantissa will be less than actual amountInMantissa if incentive > 0)
|
|
1138
|
+
amountInMantissa = ((amountOutMantissa * EXP_SCALE) + tokenInToOutConversion - 1) / tokenInToOutConversion; //round-up
|
|
1139
|
+
}
|
|
1140
|
+
|
|
1141
|
+
/// @dev Check if msg.sender is allowed to convert as per onlyForPrivateConversions flag
|
|
1142
|
+
/// @param tokenAddressIn Address of the token to convert
|
|
1143
|
+
/// @param tokenAddressOut Address of the token to get after conversion
|
|
1144
|
+
/// @custom:error ConversionEnabledOnlyForPrivateConversions is thrown when conversion is only enabled for private conversion
|
|
1145
|
+
function _checkPrivateConversion(address tokenAddressIn, address tokenAddressOut) internal view {
|
|
1146
|
+
bool isConverter = (address(converterNetwork) != address(0)) && converterNetwork.isTokenConverter(msg.sender);
|
|
1147
|
+
if (
|
|
1148
|
+
(!(isConverter) &&
|
|
1149
|
+
(conversionConfigurations[tokenAddressIn][tokenAddressOut].conversionAccess ==
|
|
1150
|
+
ConversionAccessibility.ONLY_FOR_CONVERTERS))
|
|
1151
|
+
) {
|
|
1152
|
+
revert ConversionEnabledOnlyForPrivateConversions();
|
|
1153
|
+
}
|
|
1154
|
+
}
|
|
1155
|
+
|
|
1156
|
+
/// @dev To check, is conversion paused
|
|
1157
|
+
/// @custom:error ConversionTokensPaused is thrown when token conversion is paused
|
|
1158
|
+
function _checkConversionPaused() internal view {
|
|
1159
|
+
if (conversionPaused) {
|
|
1160
|
+
revert ConversionTokensPaused();
|
|
1161
|
+
}
|
|
1162
|
+
}
|
|
1163
|
+
|
|
1164
|
+
/// @dev Get base asset address of the destination contract
|
|
1165
|
+
/// @return Address of the base asset
|
|
1166
|
+
function _getDestinationBaseAsset() internal view virtual returns (address) {}
|
|
1167
|
+
}
|