├── .eslintrc ├── .gitattributes ├── .github └── workflows │ └── node.js.yml ├── .gitignore ├── .prettierrc ├── .solcover.js ├── CONTRACTS.md ├── LICENSE ├── README.md ├── contracts ├── Auth2.sol ├── CDPRegistry.sol ├── CollateralRegistry.sol ├── Migrations.sol ├── ParametersBatchUpdater.sol ├── USDP.sol ├── Vault.sol ├── VaultParameters.sol ├── auction │ └── LiquidationAuction02.sol ├── helpers │ ├── AssetParametersViewer.sol │ ├── CDPViewer.sol │ ├── ERC20Like.sol │ ├── IUniswapV2Factory.sol │ ├── IUniswapV2PairFull.sol │ ├── Math.sol │ ├── ReentrancyGuard.sol │ ├── SafeMath.sol │ └── TransferHelper.sol ├── interfaces │ ├── IAggregator.sol │ ├── IBearingAssetOracle.sol │ ├── ICDPRegistry.sol │ ├── ICollateralRegistry.sol │ ├── ICurvePool.sol │ ├── ICurveProvider.sol │ ├── ICurveRegistry.sol │ ├── IERC20WithOptional.sol │ ├── IFoundation.sol │ ├── IOracleEth.sol │ ├── IOracleRegistry.sol │ ├── IOracleUsd.sol │ ├── IStETH.sol │ ├── IStEthPriceFeed.sol │ ├── IStableSwap.sol │ ├── IStableSwapStateOracle.sol │ ├── IToken.sol │ ├── IVault.sol │ ├── IVaultParameters.sol │ ├── IWETH.sol │ ├── IWrappedToUnderlyingOracle.sol │ ├── IWstEthToken.sol │ ├── IcyToken.sol │ ├── IyvToken.sol │ ├── curve │ │ ├── ICurvePoolBase.sol │ │ ├── ICurvePoolCrypto.sol │ │ └── ICurvePoolMeta.sol │ ├── swappers │ │ ├── ISwapper.sol │ │ └── ISwappersRegistry.sol │ ├── vault-managers │ │ └── parameters │ │ │ ├── IAssetsBooleanParameters.sol │ │ │ ├── IVaultManagerBorrowFeeParameters.sol │ │ │ └── IVaultManagerParameters.sol │ └── wrapped-assets │ │ ├── IBoneLocker.sol │ │ ├── IBoneToken.sol │ │ ├── ISushiSwapLpToken.sol │ │ ├── ITopDog.sol │ │ └── IWrappedAsset.sol ├── oracles │ ├── BearingAssetOracle.sol │ ├── BridgedUsdpOracle.sol │ ├── ChainlinkedKeydonixOracleMainAssetAbstract.sol │ ├── ChainlinkedKeydonixOraclePoolTokenAbstract.sol │ ├── ChainlinkedOracleMainAsset.sol │ ├── CurveLPOracle.sol │ ├── CyTokenOracle.sol │ ├── KeydonixOracleAbstract.sol │ ├── OraclePoolToken.sol │ ├── OracleRegistry.sol │ ├── OracleSimple.sol │ ├── WrappedToUnderlyingOracle.sol │ ├── WrappedToUnderlyingOracleKeydonix.sol │ ├── WstEthOracle.sol │ └── YvTokenOracle.sol ├── swappers │ ├── AbstractSwapper.sol │ ├── SwapperUniswapV2Lp.sol │ ├── SwapperWethViaCurve.sol │ ├── SwappersRegistry.sol │ └── helpers │ │ ├── CurveHelper.sol │ │ └── UniswapV2Helper.sol ├── test-helpers │ ├── ChainlinkAggregator_Mock.sol │ ├── ChainlinkOracleMainAsset_Mock.sol │ ├── CurveMock.sol │ ├── CyWETH.sol │ ├── DummyToken.sol │ ├── EmptyToken.sol │ ├── FoundationMock.sol │ ├── IAssetTestsMint.sol │ ├── Keep3rOracleMainAsset_Mock.sol │ ├── KeydonixOracleMainAsset_Mock.sol │ ├── KeydonixOraclePoolToken_Mock.sol │ ├── KeydonixSimpleOracle_Mock.sol │ ├── OraclePoolToken_Mock.sol │ ├── SimpleOracle_Mock.sol │ ├── StETH.sol │ ├── StETHCurvePool.sol │ ├── StETHPriceFeed.sol │ ├── StETHStableSwapOracle.sol │ ├── SwapperMock.sol │ ├── USDPMock.sol │ ├── UniswapV2Library.sol │ ├── UniswapV2Router02.sol │ ├── WETHMock.sol │ ├── WrappedAssetMock.sol │ ├── WstETH.sol │ └── YvWETH.sol ├── vault-managers │ ├── BaseCDPManager.sol │ ├── CDPManager01.sol │ ├── CDPManager_Fallback.sol │ └── parameters │ │ ├── AssetParameters.sol │ │ ├── AssetsBooleanParameters.sol │ │ ├── VaultManagerBorrowFeeParameters.sol │ │ └── VaultManagerParameters.sol └── wrapped-assets │ ├── shiba │ ├── WSSLPUserProxy.sol │ └── WrappedShibaSwapLp.sol │ └── test-helpers │ ├── BoneLocker_Mock.sol │ ├── BoneToken_Mock.sol │ ├── MigratorShib_Mock.sol │ ├── SushiSwapLpToken_Mock.sol │ └── TopDog_Mock.sol ├── doc ├── dev-full │ ├── AbstractSwapper.md │ ├── AssetParameters.md │ ├── AssetParametersViewer.md │ ├── AssetsBooleanParameters.md │ ├── Auth.md │ ├── Auth2.md │ ├── BaseCDPManager.md │ ├── BearingAssetOracle.md │ ├── BridgedUsdpOracle.md │ ├── CDPManager01.md │ ├── CDPManager01_Fallback.md │ ├── CDPRegistry.md │ ├── CDPViewer.md │ ├── ChainlinkedKeydonixOracleMainAssetAbstract.md │ ├── ChainlinkedKeydonixOraclePoolTokenAbstract.md │ ├── ChainlinkedOracleMainAsset.md │ ├── ChainlinkedOracleSimple.md │ ├── CollateralRegistry.md │ ├── CurveHelper.md │ ├── CurveLPOracle.md │ ├── CyTokenOracle.md │ ├── ERC20Like.md │ ├── IUniswapV2Factory.md │ ├── IUniswapV2PairFull.md │ ├── KeydonixOracleAbstract.md │ ├── LiquidationAuction02.md │ ├── Math.md │ ├── Migrations.md │ ├── OraclePoolToken.md │ ├── OracleRegistry.md │ ├── OracleSimple.md │ ├── OracleSimplePoolToken.md │ ├── ParametersBatchUpdater.md │ ├── ReentrancyGuard.md │ ├── SafeMath.md │ ├── SwapperUniswapV2Lp.md │ ├── SwapperWethViaCurve.md │ ├── SwappersRegistry.md │ ├── TransferHelper.md │ ├── USDP.md │ ├── UniswapV2Helper.md │ ├── UnitProxy.md │ ├── Vault.md │ ├── VaultManagerBorrowFeeParameters.md │ ├── VaultManagerParameters.md │ ├── VaultParameters.md │ ├── WSSLPUserProxy.md │ ├── WrappedShibaSwapLp.md │ ├── WrappedToUnderlyingOracle.md │ ├── WrappedToUnderlyingOracleKeydonix.md │ ├── WstEthOracle.md │ └── YvTokenOracle.md └── dev │ ├── CDPManager.md │ ├── CDPRegistry.md │ ├── CollateralRegistry.md │ ├── LiquidationAuction02.md │ ├── ParametersBatchUpdater.md │ ├── USDP.md │ ├── Vault.md │ └── oracles │ ├── ChainlinkedOracleMainAsset.md │ ├── CurveLPOracle.md │ ├── OraclePoolToken.md │ └── OracleRegistry.md ├── hardhat.config.js ├── lib ├── constants.js └── deployments │ ├── core.js │ ├── swappers.js │ └── wrappedSSLP.js ├── migrations ├── 1_initial_migration.js └── 2_deploy_contracts.js ├── network_constants.js ├── package.json ├── scripts └── deployTestWrappedSslp.js ├── test ├── AssetsBooleanParameters.test.js ├── BearingAssetsOracle.test.js ├── CDPManager_BearingAssets.test.js ├── CDPManager_Keep3r_Chainlink.test.js ├── CDPManager_Keydonix.test.js ├── CDPManager_Leverage.test.js ├── CDPManager_PoolToken_Keep3r_Chainlink.test.js ├── CDPManager_PoolToken_Keydonix.test.js ├── CDPManager_WrappedAssets.test.js ├── CollateralRegistry.test.js ├── CurveLPOracle.test.js ├── CyTokenOracle.test.js ├── LiquidationAuction.test.js ├── LiquidationTrigger_BearingAssets.test.js ├── LiquidationTrigger_Chainlink.test.js ├── LiquidationTrigger_Keep3r.test.js ├── LiquidationTrigger_Keydonix.test.js ├── LiquidationTrigger_PoolToken_Chainlink.test.js ├── LiquidationTrigger_PoolToken_Keep3r.test.js ├── LiquidationTrigger_PoolToken_Keydonix.test.js ├── LiquidationTrigger_WrappedAssets.test.js ├── OracleRegistry.test.js ├── Parameters.test.js ├── USDP.test.js ├── VaultManagerBorrowFeeParameters.test.js ├── WstEthOracle.test.js ├── YvTokenOracle.test.js ├── helpers │ ├── UniswapV2DeployCode.js │ ├── balances.js │ ├── cdpManagerWrappers.js │ ├── decodeLogs.js │ ├── deploy.js │ ├── deployUtils.js │ ├── ethersUtils.js │ ├── sign.js │ ├── time.js │ ├── timeTravel.js │ ├── utils.js │ └── wrappers.js ├── oracles │ ├── BridgedUsdpOracle.test.js │ └── WrappedToUnderlyingOracleKeydonix.test.js ├── swappers │ ├── SwapperUniswapV2Lp.test.js │ ├── SwapperWethViaCurve.test.js │ └── SwappersRegistry.test.js └── wrapped-assets │ ├── WrappedShibaSwapLp.test.js │ └── helpers │ ├── TopDogLogic.js │ └── TopDogLogic.test.js ├── tests_integration └── swappers │ ├── SwapperUniswapV2Lp.test.js │ └── SwapperWethViaCurve.test.js ├── truffle.js └── yarn.lock /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends" : [ 3 | "standard", 4 | "plugin:promise/recommended", 5 | "prettier" 6 | ], 7 | "plugins": [ 8 | "mocha-no-only", 9 | "promise", 10 | "prettier" 11 | ], 12 | "env": { 13 | "browser" : true, 14 | "node" : true, 15 | "mocha" : true, 16 | "jest" : true 17 | }, 18 | "globals" : { 19 | "artifacts": false, 20 | "contract": false, 21 | "assert": false, 22 | "web3": false 23 | }, 24 | "rules": { 25 | 26 | // Strict mode 27 | "strict": ["error", "global"], 28 | 29 | // Code style 30 | "camelcase": ["error", {"properties": "always"}], 31 | "comma-dangle": ["error", "always-multiline"], 32 | "comma-spacing": ["error", {"before": false, "after": true}], 33 | "dot-notation": ["error", {"allowKeywords": true, "allowPattern": ""}], 34 | "eol-last": ["error", "always"], 35 | "eqeqeq": ["error", "smart"], 36 | "generator-star-spacing": ["error", "before"], 37 | "indent": ["error", 2], 38 | "linebreak-style": ["error", "unix"], 39 | "max-len": ["error", 120, 2], 40 | "no-debugger": "off", 41 | "no-dupe-args": "error", 42 | "no-dupe-keys": "error", 43 | "no-mixed-spaces-and-tabs": ["error", "smart-tabs"], 44 | "no-redeclare": ["error", {"builtinGlobals": true}], 45 | "no-trailing-spaces": ["error", { "skipBlankLines": false }], 46 | "no-undef": "error", 47 | "no-use-before-define": "off", 48 | "no-var": "error", 49 | "object-curly-spacing": ["error", "always"], 50 | "prefer-const": "error", 51 | "quotes": ["error", "single"], 52 | "semi": ["error", "always"], 53 | "space-before-function-paren": ["error", "always"], 54 | 55 | "mocha-no-only/mocha-no-only": ["error"], 56 | 57 | "promise/always-return": "off", 58 | "promise/avoid-new": "off", 59 | "prettier/prettier": ["error"] 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | *.sol linguist-language=Solidity 4 | -------------------------------------------------------------------------------- /.github/workflows/node.js.yml: -------------------------------------------------------------------------------- 1 | name: Node.js CI 2 | 3 | on: push 4 | 5 | jobs: 6 | build: 7 | runs-on: ubuntu-latest 8 | 9 | strategy: 10 | matrix: 11 | node-version: [16.x] 12 | # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ 13 | 14 | steps: 15 | - uses: actions/checkout@v2 16 | - name: Use Node.js ${{ matrix.node-version }} 17 | uses: actions/setup-node@v2 18 | with: 19 | node-version: ${{ matrix.node-version }} 20 | cache: 'yarn' 21 | - name: Install dependencies 22 | run: yarn install --frozen-lockfile 23 | - name: Run tests 24 | run: npx hardhat test 25 | env: 26 | USE_DEPLOYMENT: 1 -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules/ 2 | /.env 3 | /.idea/ 4 | /build/ 5 | coverage 6 | coverage.json 7 | /package-lock.json 8 | 9 | **/artifacts/ 10 | /DEPLOYED/ 11 | /cache/ 12 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "semi": true, 3 | "singleQuote": true, 4 | "printWidth": 120, 5 | "tabWidth": 2, 6 | "bracketSpacing": true, 7 | "useTabs": true, 8 | "parser": "babylon", 9 | "jsxBracketSameLine": false 10 | } 11 | -------------------------------------------------------------------------------- /.solcover.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | skipFiles: ['helpers', 'test-helpers', 'Migrations.sol'] 3 | }; 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Unit Protocol 2 | 3 | [Unit Protocol](https://unit.xyz/) is a decentralized protocol that allows you to mint stablecoin [USDP](contracts/USDP.sol) using a variety of tokens as collateral. 4 | 5 | The Unit Protocol offers a robust infrastructure for stablecoin minting and management, backed by a diverse range of collateral assets. It emphasizes security, flexibility, and efficient governance, making it a comprehensive solution in the DeFi space. 6 | 7 | See the [docs](https://unit-protocol.gitbook.io/docs/). 8 | 9 | ## Deployed contracts 10 | 11 | See in additional document: [Contract addresses](CONTRACTS.md) 12 | 13 | ## Oracles 14 | 15 | #### [Oracle contracts](CONTRACTS.md#Oracles) 16 | 17 | The most important part of the onchain stablecoin protocol is the oracles that allow the system to measure asset values on the fly. Unit Protocol stablecoin system currently uses the following types of onchain oracles: 18 | 19 | - Direct wrappers for existing [Chainlink feeds](https://data.chain.link/) 20 | - Custom wrappers for DeFi primitives (aka bearing assets) using Chainlink-based wrappers 21 | - [Keydonix-based](https://github.com/keydonix/uniswap-oracle) time-weighted average price (TWAP) oracle implementation that uses a window of [100; 255] blocks for price calculation 22 | - [Keep3rOracle-based](https://github.com/keep3r-network/keep3r.network/blob/master/contracts/jobs/UniswapV2Oracle.sol) time-weighted average price (TWAP) oracle implementation that uses a window of 1.5 - 2.5h for price calculation 23 | - Oracles for different LP tokens 24 | 25 | Info about concrete oracle used for collateral is listed on collateral page on https://unit.xyz/ 26 | -------------------------------------------------------------------------------- /contracts/Auth2.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: bsl-1.1 2 | 3 | /* 4 | Copyright 2021 Unit Protocol: Artem Zakharov (az@unit.xyz). 5 | */ 6 | pragma solidity 0.7.6; 7 | 8 | import "./VaultParameters.sol"; 9 | 10 | 11 | /** 12 | * @title Auth2 13 | * @dev Manages USDP's system access 14 | * @dev copy of Auth from VaultParameters.sol but with immutable vaultParameters for saving gas 15 | **/ 16 | contract Auth2 { 17 | 18 | // address of the the contract with vault parameters 19 | VaultParameters public immutable vaultParameters; 20 | 21 | constructor(address _parameters) { 22 | require(_parameters != address(0), "Unit Protocol: ZERO_ADDRESS"); 23 | 24 | vaultParameters = VaultParameters(_parameters); 25 | } 26 | 27 | // ensures tx's sender is a manager 28 | modifier onlyManager() { 29 | require(vaultParameters.isManager(msg.sender), "Unit Protocol: AUTH_FAILED"); 30 | _; 31 | } 32 | 33 | // ensures tx's sender is able to modify the Vault 34 | modifier hasVaultAccess() { 35 | require(vaultParameters.canModifyVault(msg.sender), "Unit Protocol: AUTH_FAILED"); 36 | _; 37 | } 38 | 39 | // ensures tx's sender is the Vault 40 | modifier onlyVault() { 41 | require(msg.sender == vaultParameters.vault(), "Unit Protocol: AUTH_FAILED"); 42 | _; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /contracts/CollateralRegistry.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: bsl-1.1 2 | 3 | /* 4 | Copyright 2020 Unit Protocol: Artem Zakharov (az@unit.xyz). 5 | */ 6 | pragma solidity ^0.7.1; 7 | pragma experimental ABIEncoderV2; 8 | 9 | 10 | import "./VaultParameters.sol"; 11 | 12 | 13 | /** 14 | * @title CollateralRegistry 15 | **/ 16 | contract CollateralRegistry is Auth { 17 | 18 | event CollateralAdded(address indexed asset); 19 | event CollateralRemoved(address indexed asset); 20 | 21 | mapping(address => uint) public collateralId; 22 | 23 | address[] public collateralList; 24 | 25 | constructor(address _vaultParameters, address[] memory assets) Auth(_vaultParameters) { 26 | for (uint i = 0; i < assets.length; i++) { 27 | require(!isCollateral(assets[i]), "Unit Protocol: ALREADY_EXIST"); 28 | collateralList.push(assets[i]); 29 | collateralId[assets[i]] = i; 30 | emit CollateralAdded(assets[i]); 31 | } 32 | } 33 | 34 | function addCollateral(address asset) public onlyManager { 35 | require(asset != address(0), "Unit Protocol: ZERO_ADDRESS"); 36 | 37 | require(!isCollateral(asset), "Unit Protocol: ALREADY_EXIST"); 38 | 39 | collateralId[asset] = collateralList.length; 40 | collateralList.push(asset); 41 | 42 | emit CollateralAdded(asset); 43 | } 44 | 45 | function removeCollateral(address asset) public onlyManager { 46 | require(asset != address(0), "Unit Protocol: ZERO_ADDRESS"); 47 | 48 | require(isCollateral(asset), "Unit Protocol: DOES_NOT_EXIST"); 49 | 50 | uint id = collateralId[asset]; 51 | 52 | delete collateralId[asset]; 53 | 54 | uint lastId = collateralList.length - 1; 55 | 56 | if (id != lastId) { 57 | address lastCollateral = collateralList[lastId]; 58 | collateralList[id] = lastCollateral; 59 | collateralId[lastCollateral] = id; 60 | } 61 | 62 | collateralList.pop(); 63 | 64 | emit CollateralRemoved(asset); 65 | } 66 | 67 | function isCollateral(address asset) public view returns(bool) { 68 | if (collateralList.length == 0) { return false; } 69 | return collateralId[asset] != 0 || collateralList[0] == asset; 70 | } 71 | 72 | function collaterals() external view returns (address[] memory) { 73 | return collateralList; 74 | } 75 | 76 | function collateralsCount() external view returns (uint) { 77 | return collateralList.length; 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /contracts/Migrations.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: bsl-1.1 2 | 3 | 4 | pragma solidity 0.7.6; 5 | 6 | contract Migrations { 7 | address public owner; 8 | uint public last_completed_migration; 9 | 10 | constructor() { 11 | owner = msg.sender; 12 | } 13 | 14 | modifier restricted() { 15 | if (msg.sender == owner) _; 16 | } 17 | 18 | function setCompleted(uint completed) public restricted { 19 | last_completed_migration = completed; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /contracts/helpers/ERC20Like.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: bsl-1.1 2 | 3 | /* 4 | Copyright 2020 Unit Protocol: Artem Zakharov (az@unit.xyz). 5 | */ 6 | pragma solidity 0.7.6; 7 | 8 | 9 | interface ERC20Like { 10 | function balanceOf(address) external view returns (uint); 11 | function decimals() external view returns (uint8); 12 | function transfer(address, uint256) external returns (bool); 13 | function transferFrom(address, address, uint256) external returns (bool); 14 | function totalSupply() external view returns (uint256); 15 | } 16 | -------------------------------------------------------------------------------- /contracts/helpers/IUniswapV2Factory.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: bsl-1.1 2 | 3 | /* 4 | Copyright 2020 Unit Protocol: Artem Zakharov (az@unit.xyz). 5 | */ 6 | pragma solidity 0.7.6; 7 | 8 | interface IUniswapV2Factory { 9 | event PairCreated(address indexed token0, address indexed token1, address pair, uint); 10 | 11 | function getPair(address tokenA, address tokenB) external view returns (address pair); 12 | function allPairs(uint) external view returns (address pair); 13 | function allPairsLength() external view returns (uint); 14 | 15 | function feeTo() external view returns (address); 16 | function feeToSetter() external view returns (address); 17 | 18 | function createPair(address tokenA, address tokenB) external returns (address pair); 19 | } 20 | -------------------------------------------------------------------------------- /contracts/helpers/IUniswapV2PairFull.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: bsl-1.1 2 | 3 | /* 4 | Copyright 2020 Unit Protocol: Artem Zakharov (az@unit.xyz). 5 | */ 6 | pragma solidity 0.7.6; 7 | 8 | interface IUniswapV2PairFull { 9 | event Approval(address indexed owner, address indexed spender, uint value); 10 | event Transfer(address indexed from, address indexed to, uint value); 11 | 12 | function name() external pure returns (string memory); 13 | function symbol() external pure returns (string memory); 14 | function decimals() external pure returns (uint8); 15 | function totalSupply() external view returns (uint); 16 | function balanceOf(address owner) external view returns (uint); 17 | function allowance(address owner, address spender) external view returns (uint); 18 | 19 | function approve(address spender, uint value) external returns (bool); 20 | function transfer(address to, uint value) external returns (bool); 21 | function transferFrom(address from, address to, uint value) external returns (bool); 22 | 23 | function DOMAIN_SEPARATOR() external view returns (bytes32); 24 | function PERMIT_TYPEHASH() external pure returns (bytes32); 25 | function nonces(address owner) external view returns (uint); 26 | 27 | function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external; 28 | 29 | event Mint(address indexed sender, uint amount0, uint amount1); 30 | event Burn(address indexed sender, uint amount0, uint amount1, address indexed to); 31 | event Swap( 32 | address indexed sender, 33 | uint amount0In, 34 | uint amount1In, 35 | uint amount0Out, 36 | uint amount1Out, 37 | address indexed to 38 | ); 39 | event Sync(uint112 reserve0, uint112 reserve1); 40 | 41 | function MINIMUM_LIQUIDITY() external pure returns (uint); 42 | function factory() external view returns (address); 43 | function token0() external view returns (address); 44 | function token1() external view returns (address); 45 | function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast); 46 | function price0CumulativeLast() external view returns (uint); 47 | function price1CumulativeLast() external view returns (uint); 48 | function kLast() external view returns (uint); 49 | 50 | function mint(address to) external returns (uint liquidity); 51 | function burn(address to) external returns (uint amount0, uint amount1); 52 | function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external; 53 | function skim(address to) external; 54 | function sync() external; 55 | 56 | function initialize(address, address) external; 57 | } 58 | -------------------------------------------------------------------------------- /contracts/helpers/Math.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: bsl-1.1 2 | 3 | /* 4 | Copyright 2020 Unit Protocol: Artem Zakharov (az@unit.xyz). 5 | */ 6 | pragma solidity 0.7.6; 7 | 8 | /** 9 | * @dev Standard math utilities missing in the Solidity language. 10 | */ 11 | library Math { 12 | /** 13 | * @dev Returns the largest of two numbers. 14 | */ 15 | function max(uint256 a, uint256 b) internal pure returns (uint256) { 16 | return a >= b ? a : b; 17 | } 18 | 19 | /** 20 | * @dev Returns the smallest of two numbers. 21 | */ 22 | function min(uint256 a, uint256 b) internal pure returns (uint256) { 23 | return a < b ? a : b; 24 | } 25 | 26 | /** 27 | * @dev Returns the average of two numbers. The result is rounded towards 28 | * zero. 29 | */ 30 | function average(uint256 a, uint256 b) internal pure returns (uint256) { 31 | // (a + b) / 2 can overflow, so we distribute 32 | return (a / 2) + (b / 2) + ((a % 2 + b % 2) / 2); 33 | } 34 | 35 | /** 36 | * @dev babylonian method (https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method) 37 | **/ 38 | function sqrt(uint x) internal pure returns (uint y) { 39 | if (x > 3) { 40 | uint z = x / 2 + 1; 41 | y = x; 42 | while (z < y) { 43 | y = z; 44 | z = (x / z + z) / 2; 45 | } 46 | } else if (x != 0) { 47 | y = 1; 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /contracts/helpers/ReentrancyGuard.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity 0.7.6; 4 | 5 | /** 6 | * @dev Contract module that helps prevent reentrant calls to a function. 7 | * 8 | * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier 9 | * available, which can be applied to functions to make sure there are no nested 10 | * (reentrant) calls to them. 11 | * 12 | * Note that because there is a single `nonReentrant` guard, functions marked as 13 | * `nonReentrant` may not call one another. This can be worked around by making 14 | * those functions `private`, and then adding `external` `nonReentrant` entry 15 | * points to them. 16 | * 17 | * TIP: If you would like to learn more about reentrancy and alternative ways 18 | * to protect against it, check out our blog post 19 | * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. 20 | */ 21 | contract ReentrancyGuard { 22 | // Booleans are more expensive than uint256 or any type that takes up a full 23 | // word because each write operation emits an extra SLOAD to first read the 24 | // slot's contents, replace the bits taken up by the boolean, and then write 25 | // back. This is the compiler's defense against contract upgrades and 26 | // pointer aliasing, and it cannot be disabled. 27 | 28 | // The values being non-zero value makes deployment a bit more expensive, 29 | // but in exchange the refund on every call to nonReentrant will be lower in 30 | // amount. Since refunds are capped to a percentage of the total 31 | // transaction's gas, it is best to keep them low in cases like this one, to 32 | // increase the likelihood of the full refund coming into effect. 33 | uint256 private constant _NOT_ENTERED = 1; 34 | uint256 private constant _ENTERED = 2; 35 | 36 | uint256 private _status; 37 | 38 | constructor () { 39 | _status = _NOT_ENTERED; 40 | } 41 | 42 | /** 43 | * @dev Prevents a contract from calling itself, directly or indirectly. 44 | * Calling a `nonReentrant` function from another `nonReentrant` 45 | * function is not supported. It is possible to prevent this from happening 46 | * by making the `nonReentrant` function external, and make it call a 47 | * `private` function that does the actual work. 48 | */ 49 | modifier nonReentrant() { 50 | // On the first call to nonReentrant, _notEntered will be true 51 | require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); 52 | 53 | // Any calls to nonReentrant after this point will fail 54 | _status = _ENTERED; 55 | 56 | _; 57 | 58 | // By storing the original value once again, a refund is triggered (see 59 | // https://eips.ethereum.org/EIPS/eip-2200) 60 | _status = _NOT_ENTERED; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /contracts/helpers/SafeMath.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: bsl-1.1 2 | 3 | /* 4 | Copyright 2020 Unit Protocol: Artem Zakharov (az@unit.xyz). 5 | */ 6 | pragma solidity 0.7.6; 7 | 8 | 9 | /** 10 | * @title SafeMath 11 | * @dev Math operations with safety checks that throw on error 12 | */ 13 | library SafeMath { 14 | 15 | /** 16 | * @dev Multiplies two numbers, throws on overflow. 17 | */ 18 | function mul(uint256 a, uint256 b) internal pure returns (uint256 c) { 19 | if (a == 0) { 20 | return 0; 21 | } 22 | c = a * b; 23 | assert(c / a == b); 24 | return c; 25 | } 26 | 27 | /** 28 | * @dev Integer division of two numbers, truncating the quotient. 29 | */ 30 | function div(uint256 a, uint256 b) internal pure returns (uint256) { 31 | require(b != 0, "SafeMath: division by zero"); 32 | return a / b; 33 | } 34 | 35 | /** 36 | * @dev Subtracts two numbers, throws on overflow (i.e. if subtrahend is greater than minuend). 37 | */ 38 | function sub(uint256 a, uint256 b) internal pure returns (uint256) { 39 | assert(b <= a); 40 | return a - b; 41 | } 42 | 43 | /** 44 | * @dev Adds two numbers, throws on overflow. 45 | */ 46 | function add(uint256 a, uint256 b) internal pure returns (uint256 c) { 47 | c = a + b; 48 | assert(c >= a); 49 | return c; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /contracts/helpers/TransferHelper.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0-or-later 2 | 3 | /* 4 | Copyright 2020 Unit Protocol: Artem Zakharov (az@unit.xyz). 5 | */ 6 | pragma solidity 0.7.6; 7 | 8 | // helper methods for interacting with ERC20 tokens and sending ETH that do not consistently return true/false 9 | library TransferHelper { 10 | function safeApprove(address token, address to, uint value) internal { 11 | // bytes4(keccak256(bytes('approve(address,uint256)'))); 12 | (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x095ea7b3, to, value)); 13 | require(success && (data.length == 0 || abi.decode(data, (bool))), 'TransferHelper: APPROVE_FAILED'); 14 | } 15 | 16 | function safeTransfer(address token, address to, uint value) internal { 17 | // bytes4(keccak256(bytes('transfer(address,uint256)'))); 18 | (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0xa9059cbb, to, value)); 19 | require(success && (data.length == 0 || abi.decode(data, (bool))), 'TransferHelper: TRANSFER_FAILED'); 20 | } 21 | 22 | function safeTransferFrom(address token, address from, address to, uint value) internal { 23 | // bytes4(keccak256(bytes('transferFrom(address,address,uint256)'))); 24 | (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x23b872dd, from, to, value)); 25 | require(success && (data.length == 0 || abi.decode(data, (bool))), 'TransferHelper: TRANSFER_FROM_FAILED'); 26 | } 27 | 28 | function safeTransferETH(address to, uint value) internal { 29 | (bool success,) = to.call{value:value}(new bytes(0)); 30 | require(success, 'TransferHelper: ETH_TRANSFER_FAILED'); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /contracts/interfaces/IAggregator.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: bsl-1.1 2 | 3 | /* 4 | Copyright 2020 Unit Protocol: Artem Zakharov (az@unit.xyz). 5 | */ 6 | pragma solidity 0.7.6; 7 | 8 | 9 | /** 10 | **/ 11 | interface IAggregator { 12 | function latestAnswer() external view returns (int256); 13 | function latestTimestamp() external view returns (uint256); 14 | function latestRound() external view returns (uint256); 15 | function getAnswer(uint256 roundId) external view returns (int256); 16 | function getTimestamp(uint256 roundId) external view returns (uint256); 17 | function decimals() external view returns (uint256); 18 | 19 | function latestRoundData() 20 | external 21 | view 22 | returns ( 23 | uint80 roundId, 24 | int256 answer, 25 | uint256 startedAt, 26 | uint256 updatedAt, 27 | uint80 answeredInRound 28 | ); 29 | 30 | event AnswerUpdated(int256 indexed current, uint256 indexed roundId, uint256 timestamp); 31 | event NewRound(uint256 indexed roundId, address indexed startedBy, uint256 startedAt); 32 | } 33 | -------------------------------------------------------------------------------- /contracts/interfaces/IBearingAssetOracle.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: bsl-1.1 2 | 3 | /* 4 | Copyright 2020 Unit Protocol: Artem Zakharov (az@unit.xyz). 5 | */ 6 | pragma solidity ^0.7.6; 7 | 8 | interface IBearingAssetOracle { 9 | function assetToUsd ( address bearing, uint256 amount ) external view returns ( uint256 ); 10 | function bearingToUnderlying ( address bearing, uint256 amount ) external view returns ( address, uint256 ); 11 | function oracleRegistry ( ) external view returns ( address ); 12 | function setUnderlying ( address bearing, address underlying ) external; 13 | function vaultParameters ( ) external view returns ( address ); 14 | } 15 | -------------------------------------------------------------------------------- /contracts/interfaces/ICDPRegistry.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: bsl-1.1 2 | 3 | /* 4 | Copyright 2020 Unit Protocol: Artem Zakharov (az@unit.xyz). 5 | */ 6 | pragma solidity ^0.7.6; 7 | pragma experimental ABIEncoderV2; 8 | 9 | interface ICDPRegistry { 10 | 11 | struct CDP { 12 | address asset; 13 | address owner; 14 | } 15 | 16 | function batchCheckpoint ( address[] calldata assets, address[] calldata owners ) external; 17 | function batchCheckpointForAsset ( address asset, address[] calldata owners ) external; 18 | function checkpoint ( address asset, address owner ) external; 19 | function cr ( ) external view returns ( address ); 20 | function getAllCdps ( ) external view returns ( CDP[] memory r ); 21 | function getCdpsByCollateral ( address asset ) external view returns ( CDP[] memory cdps ); 22 | function getCdpsByOwner ( address owner ) external view returns ( CDP[] memory r ); 23 | function getCdpsCount ( ) external view returns ( uint256 totalCdpCount ); 24 | function getCdpsCountForCollateral ( address asset ) external view returns ( uint256 ); 25 | function isAlive ( address asset, address owner ) external view returns ( bool ); 26 | function isListed ( address asset, address owner ) external view returns ( bool ); 27 | function vault ( ) external view returns ( address ); 28 | } 29 | -------------------------------------------------------------------------------- /contracts/interfaces/ICollateralRegistry.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: bsl-1.1 2 | 3 | /* 4 | Copyright 2020 Unit Protocol: Artem Zakharov (az@unit.xyz). 5 | */ 6 | pragma solidity ^0.7.6; 7 | 8 | interface ICollateralRegistry { 9 | function addCollateral ( address asset ) external; 10 | function collateralId ( address ) external view returns ( uint256 ); 11 | function collaterals ( ) external view returns ( address[] memory ); 12 | function removeCollateral ( address asset ) external; 13 | function vaultParameters ( ) external view returns ( address ); 14 | function isCollateral ( address asset ) external view returns ( bool ); 15 | function collateralList ( uint id ) external view returns ( address ); 16 | function collateralsCount ( ) external view returns ( uint ); 17 | } 18 | -------------------------------------------------------------------------------- /contracts/interfaces/ICurvePool.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: bsl-1.1 2 | 3 | /* 4 | Copyright 2020 Unit Protocol: Artem Zakharov (az@unit.xyz). 5 | */ 6 | pragma solidity ^0.7.6; 7 | 8 | interface ICurvePool { 9 | function get_virtual_price() external view returns (uint); 10 | function coins(uint) external view returns (address); 11 | } -------------------------------------------------------------------------------- /contracts/interfaces/ICurveProvider.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: bsl-1.1 2 | 3 | /* 4 | Copyright 2020 Unit Protocol: Artem Zakharov (az@unit.xyz). 5 | */ 6 | pragma solidity ^0.7.6; 7 | 8 | interface ICurveProvider { 9 | function get_registry() external view returns (address); 10 | } -------------------------------------------------------------------------------- /contracts/interfaces/ICurveRegistry.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: bsl-1.1 2 | 3 | /* 4 | Copyright 2020 Unit Protocol: Artem Zakharov (az@unit.xyz). 5 | */ 6 | pragma solidity ^0.7.6; 7 | 8 | interface ICurveRegistry { 9 | function get_pool_from_lp_token(address) external view returns (address); 10 | function get_n_coins(address) external view returns (uint[2] memory); 11 | } -------------------------------------------------------------------------------- /contracts/interfaces/IERC20WithOptional.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: bsl-1.1 2 | 3 | /* 4 | Copyright 2021 Unit Protocol: Artem Zakharov (az@unit.xyz). 5 | */ 6 | pragma solidity ^0.7.6; 7 | 8 | import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; 9 | 10 | interface IERC20WithOptional is IERC20 { 11 | function name() external view returns (string memory); 12 | function symbol() external view returns (string memory); 13 | function decimals() external view returns (uint8); 14 | } 15 | -------------------------------------------------------------------------------- /contracts/interfaces/IFoundation.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: bsl-1.1 2 | 3 | pragma solidity ^0.7.6; 4 | 5 | interface IFoundation { 6 | function submitLiquidationFee(uint fee) external; 7 | } 8 | -------------------------------------------------------------------------------- /contracts/interfaces/IOracleEth.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: bsl-1.1 2 | 3 | /* 4 | Copyright 2020 Unit Protocol: Artem Zakharov (az@unit.xyz). 5 | */ 6 | pragma solidity ^0.7.6; 7 | 8 | interface IOracleEth { 9 | 10 | // returns Q112-encoded value 11 | // returned value 10**18 * 2**112 is 1 Ether 12 | function assetToEth(address asset, uint amount) external view returns (uint); 13 | 14 | // returns the value "as is" 15 | function ethToUsd(uint amount) external view returns (uint); 16 | 17 | // returns the value "as is" 18 | function usdToEth(uint amount) external view returns (uint); 19 | } -------------------------------------------------------------------------------- /contracts/interfaces/IOracleRegistry.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: bsl-1.1 2 | 3 | /* 4 | Copyright 2020 Unit Protocol: Artem Zakharov (az@unit.xyz). 5 | */ 6 | pragma solidity ^0.7.6; 7 | pragma abicoder v2; 8 | 9 | interface IOracleRegistry { 10 | 11 | struct Oracle { 12 | uint oracleType; 13 | address oracleAddress; 14 | } 15 | 16 | function WETH ( ) external view returns ( address ); 17 | function getKeydonixOracleTypes ( ) external view returns ( uint256[] memory ); 18 | function getOracles ( ) external view returns ( Oracle[] memory foundOracles ); 19 | function keydonixOracleTypes ( uint256 ) external view returns ( uint256 ); 20 | function maxOracleType ( ) external view returns ( uint256 ); 21 | function oracleByAsset ( address asset ) external view returns ( address ); 22 | function oracleByType ( uint256 ) external view returns ( address ); 23 | function oracleTypeByAsset ( address ) external view returns ( uint256 ); 24 | function oracleTypeByOracle ( address ) external view returns ( uint256 ); 25 | function setKeydonixOracleTypes ( uint256[] memory _keydonixOracleTypes ) external; 26 | function setOracle ( uint256 oracleType, address oracle ) external; 27 | function setOracleTypeForAsset ( address asset, uint256 oracleType ) external; 28 | function setOracleTypeForAssets ( address[] memory assets, uint256 oracleType ) external; 29 | function unsetOracle ( uint256 oracleType ) external; 30 | function unsetOracleForAsset ( address asset ) external; 31 | function unsetOracleForAssets ( address[] memory assets ) external; 32 | function vaultParameters ( ) external view returns ( address ); 33 | } 34 | -------------------------------------------------------------------------------- /contracts/interfaces/IOracleUsd.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: bsl-1.1 2 | 3 | /* 4 | Copyright 2020 Unit Protocol: Artem Zakharov (az@unit.xyz). 5 | */ 6 | pragma solidity ^0.7.6; 7 | 8 | interface IOracleUsd { 9 | 10 | // returns Q112-encoded value 11 | // returned value 10**18 * 2**112 is $1 12 | function assetToUsd(address asset, uint amount) external view returns (uint); 13 | } -------------------------------------------------------------------------------- /contracts/interfaces/IStETH.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: bsl-1.1 2 | 3 | /* 4 | Copyright 2020 Unit Protocol: Artem Zakharov (az@unit.xyz). 5 | */ 6 | pragma solidity ^0.7.6; 7 | 8 | interface IStETH { 9 | function getPooledEthByShares(uint256 _sharesAmount) external view returns (uint256); 10 | } 11 | -------------------------------------------------------------------------------- /contracts/interfaces/IStEthPriceFeed.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: bsl-1.1 2 | 3 | /* 4 | Copyright 2020 Unit Protocol: Artem Zakharov (az@unit.xyz). 5 | */ 6 | pragma solidity ^0.7.6; 7 | 8 | interface IStEthPriceFeed { 9 | function current_price() external view returns (uint256,bool); 10 | function full_price_info() external view returns (uint256,bool,uint256); 11 | } 12 | -------------------------------------------------------------------------------- /contracts/interfaces/IStableSwap.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: bsl-1.1 2 | 3 | /* 4 | Copyright 2020 Unit Protocol: Artem Zakharov (az@unit.xyz). 5 | */ 6 | pragma solidity ^0.7.6; 7 | 8 | interface IStableSwap { 9 | function get_dy(uint256 x, uint256 y, uint256 dx) external view returns (uint256); 10 | } 11 | -------------------------------------------------------------------------------- /contracts/interfaces/IStableSwapStateOracle.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: bsl-1.1 2 | 3 | /* 4 | Copyright 2020 Unit Protocol: Artem Zakharov (az@unit.xyz). 5 | */ 6 | pragma solidity ^0.7.6; 7 | 8 | interface IStableSwapStateOracle { 9 | function stethPrice() external view returns (uint256); 10 | } 11 | -------------------------------------------------------------------------------- /contracts/interfaces/IToken.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: bsl-1.1 2 | 3 | /* 4 | Copyright 2020 Unit Protocol: Artem Zakharov (az@unit.xyz). 5 | */ 6 | pragma solidity ^0.7.6; 7 | 8 | interface IToken { 9 | function decimals() external view returns (uint8); 10 | } -------------------------------------------------------------------------------- /contracts/interfaces/IVault.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: bsl-1.1 2 | 3 | /* 4 | Copyright 2020 Unit Protocol: Artem Zakharov (az@unit.xyz). 5 | */ 6 | pragma solidity ^0.7.6; 7 | 8 | interface IVault { 9 | function DENOMINATOR_1E2 ( ) external view returns ( uint256 ); 10 | function DENOMINATOR_1E5 ( ) external view returns ( uint256 ); 11 | function borrow ( address asset, address user, uint256 amount ) external returns ( uint256 ); 12 | function calculateFee ( address asset, address user, uint256 amount ) external view returns ( uint256 ); 13 | function changeOracleType ( address asset, address user, uint256 newOracleType ) external; 14 | function chargeFee ( address asset, address user, uint256 amount ) external; 15 | function col ( ) external view returns ( address ); 16 | function colToken ( address, address ) external view returns ( uint256 ); 17 | function collaterals ( address, address ) external view returns ( uint256 ); 18 | function debts ( address, address ) external view returns ( uint256 ); 19 | function depositCol ( address asset, address user, uint256 amount ) external; 20 | function depositEth ( address user ) external payable; 21 | function depositMain ( address asset, address user, uint256 amount ) external; 22 | function destroy ( address asset, address user ) external; 23 | function getTotalDebt ( address asset, address user ) external view returns ( uint256 ); 24 | function lastUpdate ( address, address ) external view returns ( uint256 ); 25 | function liquidate ( address asset, address positionOwner, uint256 mainAssetToLiquidator, uint256 colToLiquidator, uint256 mainAssetToPositionOwner, uint256 colToPositionOwner, uint256 repayment, uint256 penalty, address liquidator ) external; 26 | function liquidationBlock ( address, address ) external view returns ( uint256 ); 27 | function liquidationFee ( address, address ) external view returns ( uint256 ); 28 | function liquidationPrice ( address, address ) external view returns ( uint256 ); 29 | function oracleType ( address, address ) external view returns ( uint256 ); 30 | function repay ( address asset, address user, uint256 amount ) external returns ( uint256 ); 31 | function spawn ( address asset, address user, uint256 _oracleType ) external; 32 | function stabilityFee ( address, address ) external view returns ( uint256 ); 33 | function tokenDebts ( address ) external view returns ( uint256 ); 34 | function triggerLiquidation ( address asset, address positionOwner, uint256 initialPrice ) external; 35 | function update ( address asset, address user ) external; 36 | function usdp ( ) external view returns ( address ); 37 | function vaultParameters ( ) external view returns ( address ); 38 | function weth ( ) external view returns ( address payable ); 39 | function withdrawCol ( address asset, address user, uint256 amount ) external; 40 | function withdrawEth ( address user, uint256 amount ) external; 41 | function withdrawMain ( address asset, address user, uint256 amount ) external; 42 | } 43 | -------------------------------------------------------------------------------- /contracts/interfaces/IVaultParameters.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: bsl-1.1 2 | 3 | /* 4 | Copyright 2020 Unit Protocol: Artem Zakharov (az@unit.xyz). 5 | */ 6 | pragma solidity ^0.7.6; 7 | 8 | interface IVaultParameters { 9 | function canModifyVault ( address ) external view returns ( bool ); 10 | function foundation ( ) external view returns ( address ); 11 | function isManager ( address ) external view returns ( bool ); 12 | function isOracleTypeEnabled ( uint256, address ) external view returns ( bool ); 13 | function liquidationFee ( address ) external view returns ( uint256 ); 14 | function setCollateral ( address asset, uint256 stabilityFeeValue, uint256 liquidationFeeValue, uint256 usdpLimit, uint256[] calldata oracles ) external; 15 | function setFoundation ( address newFoundation ) external; 16 | function setLiquidationFee ( address asset, uint256 newValue ) external; 17 | function setManager ( address who, bool permit ) external; 18 | function setOracleType ( uint256 _type, address asset, bool enabled ) external; 19 | function setStabilityFee ( address asset, uint256 newValue ) external; 20 | function setTokenDebtLimit ( address asset, uint256 limit ) external; 21 | function setVaultAccess ( address who, bool permit ) external; 22 | function stabilityFee ( address ) external view returns ( uint256 ); 23 | function tokenDebtLimit ( address ) external view returns ( uint256 ); 24 | function vault ( ) external view returns ( address ); 25 | function vaultParameters ( ) external view returns ( address ); 26 | } 27 | -------------------------------------------------------------------------------- /contracts/interfaces/IWETH.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: bsl-1.1 2 | 3 | /* 4 | Copyright 2020 Unit Protocol: Artem Zakharov (az@unit.xyz). 5 | */ 6 | pragma solidity ^0.7.6; 7 | 8 | interface IWETH { 9 | function deposit() external payable; 10 | function transfer(address to, uint value) external returns (bool); 11 | function transferFrom(address from, address to, uint value) external returns (bool); 12 | function withdraw(uint) external; 13 | } -------------------------------------------------------------------------------- /contracts/interfaces/IWrappedToUnderlyingOracle.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: bsl-1.1 2 | 3 | /* 4 | Copyright 2020 Unit Protocol: Artem Zakharov (az@unit.xyz). 5 | */ 6 | pragma solidity ^0.7.6; 7 | 8 | interface IWrappedToUnderlyingOracle { 9 | function assetToUnderlying(address) external view returns (address); 10 | } 11 | -------------------------------------------------------------------------------- /contracts/interfaces/IWstEthToken.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: bsl-1.1 2 | 3 | /* 4 | Copyright 2020 Unit Protocol: Artem Zakharov (az@unit.xyz). 5 | */ 6 | pragma solidity ^0.7.6; 7 | 8 | interface IWstEthToken { 9 | function stETH() external view returns (address); 10 | function getStETHByWstETH(uint256 _wstETHAmount) external view returns (uint256); 11 | } 12 | -------------------------------------------------------------------------------- /contracts/interfaces/IcyToken.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: bsl-1.1 2 | 3 | /* 4 | Copyright 2020 Unit Protocol: Artem Zakharov (az@unit.xyz). 5 | */ 6 | pragma solidity ^0.7.6; 7 | 8 | interface IcyToken { 9 | function underlying() external view returns (address); 10 | function implementation() external view returns (address); 11 | function decimals() external view returns (uint8); 12 | function exchangeRateStored() external view returns (uint); 13 | } 14 | -------------------------------------------------------------------------------- /contracts/interfaces/IyvToken.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: bsl-1.1 2 | 3 | /* 4 | Copyright 2020 Unit Protocol: Artem Zakharov (az@unit.xyz). 5 | */ 6 | pragma solidity ^0.7.6; 7 | 8 | interface IyvToken { 9 | function token() external view returns (address); 10 | function decimals() external view returns (uint256); 11 | function pricePerShare() external view returns (uint256); 12 | function emergencyShutdown() external view returns (bool); 13 | } 14 | -------------------------------------------------------------------------------- /contracts/interfaces/curve/ICurvePoolBase.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: bsl-1.1 2 | 3 | /* 4 | Copyright 2022 Unit Protocol: Artem Zakharov (az@unit.xyz). 5 | */ 6 | pragma solidity ^0.7.6; 7 | 8 | import "../ICurvePool.sol"; 9 | 10 | interface ICurvePoolBase is ICurvePool { 11 | /** 12 | * @notice Perform an exchange between two coins 13 | * @dev Index values can be found via the `coins` public getter method 14 | * @param i Index value for the coin to send 15 | * @param j Index valie of the coin to recieve 16 | * @param _dx Amount of `i` being exchanged 17 | * @param _min_dy Minimum amount of `j` to receive 18 | * @return Actual amount of `j` received 19 | */ 20 | function exchange(int128 i, int128 j, uint256 _dx, uint256 _min_dy) external returns (uint256); 21 | 22 | function get_dy(int128 i, int128 j, uint256 _dx) external view returns (uint256); 23 | } -------------------------------------------------------------------------------- /contracts/interfaces/curve/ICurvePoolCrypto.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: bsl-1.1 2 | 3 | /* 4 | Copyright 2020 Unit Protocol: Artem Zakharov (az@unit.xyz). 5 | */ 6 | pragma solidity ^0.7.6; 7 | 8 | import "../ICurvePool.sol"; 9 | 10 | interface ICurvePoolCrypto is ICurvePool { 11 | function exchange(uint256 i, uint256 j, uint256 dx, uint256 min_dy) external; 12 | function get_dy(uint256 i, uint256 j, uint256 dx) external view returns (uint256); 13 | } -------------------------------------------------------------------------------- /contracts/interfaces/curve/ICurvePoolMeta.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: bsl-1.1 2 | 3 | /* 4 | Copyright 2022 Unit Protocol: Artem Zakharov (az@unit.xyz). 5 | */ 6 | pragma solidity ^0.7.6; 7 | 8 | import "./ICurvePoolBase.sol"; 9 | 10 | interface ICurvePoolMeta is ICurvePoolBase { 11 | 12 | function base_pool() external view returns (address); 13 | 14 | /** 15 | * @dev variant of token/3crv pool 16 | * @param i Index value for the underlying coin to send 17 | * @param j Index value of the underlying coin to recieve 18 | * @param _dx Amount of `i` being exchanged 19 | * @param _min_dy Minimum amount of `j` to receive 20 | * @return Actual amount of `j` received 21 | */ 22 | function exchange_underlying(int128 i, int128 j, uint256 _dx, uint256 _min_dy) external returns (uint256); 23 | 24 | function get_dy_underlying(int128 i, int128 j, uint256 _dx) external view returns (uint256); 25 | } -------------------------------------------------------------------------------- /contracts/interfaces/swappers/ISwapper.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: bsl-1.1 2 | 3 | /* 4 | Copyright 2022 Unit Protocol: Artem Zakharov (az@unit.xyz). 5 | */ 6 | pragma solidity 0.7.6; 7 | 8 | 9 | interface ISwapper { 10 | 11 | /** 12 | * @notice Predict asset amount after usdp swap 13 | */ 14 | function predictAssetOut(address _asset, uint256 _usdpAmountIn) external view returns (uint predictedAssetAmount); 15 | 16 | /** 17 | * @notice Predict USDP amount after asset swap 18 | */ 19 | function predictUsdpOut(address _asset, uint256 _assetAmountIn) external view returns (uint predictedUsdpAmount); 20 | 21 | /** 22 | * @notice usdp must be approved to swapper 23 | * @dev asset must be sent to user after swap 24 | */ 25 | function swapUsdpToAsset(address _user, address _asset, uint256 _usdpAmount, uint256 _minAssetAmount) external returns (uint swappedAssetAmount); 26 | 27 | /** 28 | * @notice asset must be approved to swapper 29 | * @dev usdp must be sent to user after swap 30 | */ 31 | function swapAssetToUsdp(address _user, address _asset, uint256 _assetAmount, uint256 _minUsdpAmount) external returns (uint swappedUsdpAmount); 32 | 33 | /** 34 | * @notice DO NOT SEND tokens to contract manually. For usage in contracts only. 35 | * @dev for gas saving with usage in contracts tokens must be send directly to contract instead 36 | * @dev asset must be sent to user after swap 37 | */ 38 | function swapUsdpToAssetWithDirectSending(address _user, address _asset, uint256 _usdpAmount, uint256 _minAssetAmount) external returns (uint swappedAssetAmount); 39 | 40 | /** 41 | * @notice DO NOT SEND tokens to contract manually. For usage in contracts only. 42 | * @dev for gas saving with usage in contracts tokens must be send directly to contract instead 43 | * @dev usdp must be sent to user after swap 44 | */ 45 | function swapAssetToUsdpWithDirectSending(address _user, address _asset, uint256 _assetAmount, uint256 _minUsdpAmount) external returns (uint swappedUsdpAmount); 46 | } 47 | -------------------------------------------------------------------------------- /contracts/interfaces/swappers/ISwappersRegistry.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: bsl-1.1 2 | 3 | /* 4 | Copyright 2022 Unit Protocol: Artem Zakharov (az@unit.xyz). 5 | */ 6 | pragma solidity 0.7.6; 7 | 8 | import "./ISwapper.sol"; 9 | 10 | 11 | interface ISwappersRegistry { 12 | event SwapperAdded(ISwapper swapper); 13 | event SwapperRemoved(ISwapper swapper); 14 | 15 | function getSwapperId(ISwapper _swapper) external view returns (uint); 16 | function getSwapper(uint _id) external view returns (ISwapper); 17 | function hasSwapper(ISwapper _swapper) external view returns (bool); 18 | 19 | function getSwappersLength() external view returns (uint); 20 | function getSwappers() external view returns (ISwapper[] memory); 21 | } 22 | -------------------------------------------------------------------------------- /contracts/interfaces/vault-managers/parameters/IAssetsBooleanParameters.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: bsl-1.1 2 | 3 | /* 4 | Copyright 2021 Unit Protocol: Artem Zakharov (az@unit.xyz). 5 | */ 6 | pragma solidity ^0.7.6; 7 | 8 | interface IAssetsBooleanParameters { 9 | 10 | event ValueSet(address indexed asset, uint8 param, uint256 valuesForAsset); 11 | event ValueUnset(address indexed asset, uint8 param, uint256 valuesForAsset); 12 | 13 | function get(address _asset, uint8 _param) external view returns (bool); 14 | function getAll(address _asset) external view returns (uint256); 15 | function set(address _asset, uint8 _param, bool _value) external; 16 | } 17 | -------------------------------------------------------------------------------- /contracts/interfaces/vault-managers/parameters/IVaultManagerBorrowFeeParameters.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: bsl-1.1 2 | 3 | /* 4 | Copyright 2021 Unit Protocol: Artem Zakharov (az@unit.xyz). 5 | */ 6 | pragma solidity ^0.7.6; 7 | 8 | interface IVaultManagerBorrowFeeParameters { 9 | 10 | /** 11 | * @notice 1 = 100% = 10000 basis points 12 | **/ 13 | function BASIS_POINTS_IN_1() external view returns (uint); 14 | 15 | /** 16 | * @notice Borrow fee receiver 17 | **/ 18 | function feeReceiver() external view returns (address); 19 | 20 | /** 21 | * @notice Sets the borrow fee receiver. Only manager is able to call this function 22 | * @param newFeeReceiver The address of fee receiver 23 | **/ 24 | function setFeeReceiver(address newFeeReceiver) external; 25 | 26 | /** 27 | * @notice Sets the base borrow fee in basis points (1bp = 0.01% = 0.0001). Only manager is able to call this function 28 | * @param newBaseBorrowFeeBasisPoints The borrow fee in basis points 29 | **/ 30 | function setBaseBorrowFee(uint16 newBaseBorrowFeeBasisPoints) external; 31 | 32 | /** 33 | * @notice Sets the borrow fee for a particular collateral in basis points (1bp = 0.01% = 0.0001). Only manager is able to call this function 34 | * @param asset The address of the main collateral token 35 | * @param newEnabled Is custom fee enabled for asset 36 | * @param newFeeBasisPoints The borrow fee in basis points 37 | **/ 38 | function setAssetBorrowFee(address asset, bool newEnabled, uint16 newFeeBasisPoints) external; 39 | 40 | /** 41 | * @notice Returns borrow fee for particular collateral in basis points (1bp = 0.01% = 0.0001) 42 | * @param asset The address of the main collateral token 43 | * @return feeBasisPoints The borrow fee in basis points 44 | **/ 45 | function getBorrowFee(address asset) external view returns (uint16 feeBasisPoints); 46 | 47 | /** 48 | * @notice Returns borrow fee for usdp amount for particular collateral 49 | * @param asset The address of the main collateral token 50 | * @return The borrow fee 51 | **/ 52 | function calcBorrowFeeAmount(address asset, uint usdpAmount) external view returns (uint); 53 | } 54 | -------------------------------------------------------------------------------- /contracts/interfaces/vault-managers/parameters/IVaultManagerParameters.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: bsl-1.1 2 | 3 | /* 4 | Copyright 2020 Unit Protocol: Artem Zakharov (az@unit.xyz). 5 | */ 6 | pragma solidity ^0.7.6; 7 | 8 | interface IVaultManagerParameters { 9 | function devaluationPeriod ( address ) external view returns ( uint256 ); 10 | function initialCollateralRatio ( address ) external view returns ( uint256 ); 11 | function liquidationDiscount ( address ) external view returns ( uint256 ); 12 | function liquidationRatio ( address ) external view returns ( uint256 ); 13 | function maxColPercent ( address ) external view returns ( uint256 ); 14 | function minColPercent ( address ) external view returns ( uint256 ); 15 | function setColPartRange ( address asset, uint256 min, uint256 max ) external; 16 | function setCollateral ( 17 | address asset, 18 | uint256 stabilityFeeValue, 19 | uint256 liquidationFeeValue, 20 | uint256 initialCollateralRatioValue, 21 | uint256 liquidationRatioValue, 22 | uint256 liquidationDiscountValue, 23 | uint256 devaluationPeriodValue, 24 | uint256 usdpLimit, 25 | uint256[] calldata oracles, 26 | uint256 minColP, 27 | uint256 maxColP 28 | ) external; 29 | function setDevaluationPeriod ( address asset, uint256 newValue ) external; 30 | function setInitialCollateralRatio ( address asset, uint256 newValue ) external; 31 | function setLiquidationDiscount ( address asset, uint256 newValue ) external; 32 | function setLiquidationRatio ( address asset, uint256 newValue ) external; 33 | function vaultParameters ( ) external view returns ( address ); 34 | } 35 | -------------------------------------------------------------------------------- /contracts/interfaces/wrapped-assets/IBoneLocker.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: bsl-1.1 2 | 3 | /* 4 | Copyright 2021 Unit Protocol: Artem Zakharov (az@unit.xyz). 5 | */ 6 | pragma solidity 0.7.6; 7 | 8 | /** 9 | * @dev BoneToken locker contract interface 10 | */ 11 | interface IBoneLocker { 12 | 13 | function lockInfoByUser(address, uint256) external view returns (uint256, uint256, bool); 14 | 15 | function lockingPeriod() external view returns (uint256); 16 | 17 | // function to claim all the tokens locked for a user, after the locking period 18 | function claimAllForUser(uint256 r, address user) external; 19 | 20 | // function to claim all the tokens locked by user, after the locking period 21 | function claimAll(uint256 r) external; 22 | 23 | // function to get claimable amount for any user 24 | function getClaimableAmount(address _user) external view returns(uint256); 25 | 26 | // get the left and right headers for a user, left header is the index counter till which we have already iterated, right header is basically the length of user's lockInfo array 27 | function getLeftRightCounters(address _user) external view returns(uint256, uint256); 28 | 29 | function lock(address _holder, uint256 _amount, bool _isDev) external; 30 | function setLockingPeriod(uint256 _newLockingPeriod, uint256 _newDevLockingPeriod) external; 31 | function emergencyWithdrawOwner(address _to) external; 32 | } -------------------------------------------------------------------------------- /contracts/interfaces/wrapped-assets/IBoneToken.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: bsl-1.1 2 | 3 | /* 4 | Copyright 2021 Unit Protocol: Artem Zakharov (az@unit.xyz). 5 | */ 6 | pragma solidity 0.7.6; 7 | 8 | import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; 9 | 10 | interface IBoneToken is IERC20 { 11 | function mint(address _to, uint256 _amount) external; 12 | } -------------------------------------------------------------------------------- /contracts/interfaces/wrapped-assets/ISushiSwapLpToken.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: bsl-1.1 2 | 3 | /* 4 | Copyright 2021 Unit Protocol: Artem Zakharov (az@unit.xyz). 5 | */ 6 | pragma solidity 0.7.6; 7 | 8 | import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; 9 | 10 | interface ISushiSwapLpToken is IERC20 /* IERC20WithOptional */ { 11 | function token0() external view returns (address); 12 | function token1() external view returns (address); 13 | } -------------------------------------------------------------------------------- /contracts/interfaces/wrapped-assets/ITopDog.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: bsl-1.1 2 | 3 | /* 4 | Copyright 2021 Unit Protocol: Artem Zakharov (az@unit.xyz). 5 | */ 6 | pragma solidity 0.7.6; 7 | 8 | import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; 9 | 10 | import "./IBoneLocker.sol"; 11 | import "./IBoneToken.sol"; 12 | 13 | /** 14 | * See https://etherscan.io/address/0x94235659cf8b805b2c658f9ea2d6d6ddbb17c8d7#code 15 | */ 16 | interface ITopDog { 17 | 18 | function bone() external view returns (IBoneToken); 19 | function boneLocker() external view returns (IBoneLocker); 20 | function poolInfo(uint256) external view returns (IERC20, uint256, uint256, uint256); 21 | function poolLength() external view returns (uint256); 22 | function userInfo(uint256, address) external view returns (uint256, uint256); 23 | 24 | function rewardMintPercent() external view returns (uint256); 25 | function pendingBone(uint256 _pid, address _user) external view returns (uint256); 26 | function deposit(uint256 _pid, uint256 _amount) external; 27 | function withdraw(uint256 _pid, uint256 _amount) external; 28 | 29 | function emergencyWithdraw(uint256 _pid) external; 30 | } -------------------------------------------------------------------------------- /contracts/interfaces/wrapped-assets/IWrappedAsset.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: bsl-1.1 2 | 3 | /* 4 | Copyright 2021 Unit Protocol: Artem Zakharov (az@unit.xyz). 5 | */ 6 | pragma solidity 0.7.6; 7 | 8 | import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; 9 | 10 | interface IWrappedAsset is IERC20 /* IERC20WithOptional */ { 11 | 12 | event Deposit(address indexed user, uint256 amount); 13 | event Withdraw(address indexed user, uint256 amount); 14 | event PositionMoved(address indexed userFrom, address indexed userTo, uint256 amount); 15 | 16 | event EmergencyWithdraw(address indexed user, uint256 amount); 17 | event TokenWithdraw(address indexed user, address token, uint256 amount); 18 | 19 | event FeeChanged(uint256 newFeePercent); 20 | event FeeReceiverChanged(address newFeeReceiver); 21 | event AllowedBoneLockerSelectorAdded(address boneLocker, bytes4 selector); 22 | event AllowedBoneLockerSelectorRemoved(address boneLocker, bytes4 selector); 23 | 24 | /** 25 | * @notice Get underlying token 26 | */ 27 | function getUnderlyingToken() external view returns (IERC20); 28 | 29 | /** 30 | * @notice deposit underlying token and send wrapped token to user 31 | * @dev Important! Only user or trusted contracts must be able to call this method 32 | */ 33 | function deposit(address _userAddr, uint256 _amount) external; 34 | 35 | /** 36 | * @notice get wrapped token and return underlying 37 | * @dev Important! Only user or trusted contracts must be able to call this method 38 | */ 39 | function withdraw(address _userAddr, uint256 _amount) external; 40 | 41 | /** 42 | * @notice get pending reward amount for user if reward is supported 43 | */ 44 | function pendingReward(address _userAddr) external view returns (uint256); 45 | 46 | /** 47 | * @notice claim pending reward for user if reward is supported 48 | */ 49 | function claimReward(address _userAddr) external; 50 | 51 | /** 52 | * @notice Manually move position (or its part) to another user (for example in case of liquidation) 53 | * @dev Important! Only trusted contracts must be able to call this method 54 | */ 55 | function movePosition(address _userAddrFrom, address _userAddrTo, uint256 _amount) external; 56 | 57 | /** 58 | * @dev function for checks that asset is unitprotocol wrapped asset. 59 | * @dev For wrapped assets must return keccak256("UnitProtocolWrappedAsset") 60 | */ 61 | function isUnitProtocolWrappedAsset() external view returns (bytes32); 62 | } 63 | -------------------------------------------------------------------------------- /contracts/oracles/BearingAssetOracle.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: bsl-1.1 2 | 3 | /* 4 | Copyright 2020 Unit Protocol: Artem Zakharov (az@unit.xyz). 5 | */ 6 | pragma solidity 0.7.6; 7 | 8 | import "../interfaces/IOracleUsd.sol"; 9 | import "../helpers/ERC20Like.sol"; 10 | import "../VaultParameters.sol"; 11 | import "../interfaces/IOracleRegistry.sol"; 12 | import "../interfaces/IOracleEth.sol"; 13 | 14 | /** 15 | * @title BearingAssetOracle 16 | * @dev Wrapper to quote bearing assets like xSUSHI 17 | **/ 18 | contract BearingAssetOracle is IOracleUsd, Auth { 19 | 20 | IOracleRegistry public immutable oracleRegistry; 21 | 22 | mapping (address => address) underlyings; 23 | 24 | event NewUnderlying(address indexed bearing, address indexed underlying); 25 | 26 | constructor(address _vaultParameters, address _oracleRegistry) Auth(_vaultParameters) { 27 | require(_vaultParameters != address(0) && _oracleRegistry != address(0), "Unit Protocol: ZERO_ADDRESS"); 28 | oracleRegistry = IOracleRegistry(_oracleRegistry); 29 | } 30 | 31 | function setUnderlying(address bearing, address underlying) external onlyManager { 32 | underlyings[bearing] = underlying; 33 | emit NewUnderlying(bearing, underlying); 34 | } 35 | 36 | // returns Q112-encoded value 37 | function assetToUsd(address bearing, uint amount) public override view returns (uint) { 38 | if (amount == 0) return 0; 39 | (address underlying, uint underlyingAmount) = bearingToUnderlying(bearing, amount); 40 | IOracleUsd _oracleForUnderlying = IOracleUsd(oracleRegistry.oracleByAsset(underlying)); 41 | require(address(_oracleForUnderlying) != address(0), "Unit Protocol: ORACLE_NOT_FOUND"); 42 | return _oracleForUnderlying.assetToUsd(underlying, underlyingAmount); 43 | } 44 | 45 | function bearingToUnderlying(address bearing, uint amount) public view returns (address, uint) { 46 | address _underlying = underlyings[bearing]; 47 | require(_underlying != address(0), "Unit Protocol: UNDEFINED_UNDERLYING"); 48 | uint _reserve = ERC20Like(_underlying).balanceOf(address(bearing)); 49 | uint _totalSupply = ERC20Like(bearing).totalSupply(); 50 | require(amount <= _totalSupply, "Unit Protocol: AMOUNT_EXCEEDS_SUPPLY"); 51 | return (_underlying, amount * _reserve / _totalSupply); 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /contracts/oracles/BridgedUsdpOracle.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: bsl-1.1 2 | 3 | /* 4 | Copyright 2022 Unit Protocol: Artem Zakharov (az@unit.xyz). 5 | */ 6 | pragma solidity 0.7.6; 7 | 8 | import "../interfaces/IOracleUsd.sol"; 9 | import "../helpers/SafeMath.sol"; 10 | import "../Auth2.sol"; 11 | 12 | /** 13 | * @title BridgedUSDPOracle 14 | * @dev Oracle to quote bridged from other chains USDP 15 | **/ 16 | contract BridgedUsdpOracle is IOracleUsd, Auth2 { 17 | using SafeMath for uint; 18 | 19 | uint public constant Q112 = 2 ** 112; 20 | 21 | mapping (address => bool) public bridgedUsdp; 22 | 23 | event Added(address _usdp); 24 | event Removed(address _usdp); 25 | 26 | constructor(address vaultParameters, address[] memory _bridgedUsdp) Auth2(vaultParameters) { 27 | for (uint i = 0; i < _bridgedUsdp.length; i++) { 28 | _add(_bridgedUsdp[i]); 29 | } 30 | } 31 | 32 | function add(address _usdp) external onlyManager { 33 | _add(_usdp); 34 | } 35 | 36 | function _add(address _usdp) private { 37 | require(_usdp != address(0), 'Unit Protocol: ZERO_ADDRESS'); 38 | require(!bridgedUsdp[_usdp], 'Unit Protocol: ALREADY_ADDED'); 39 | 40 | bridgedUsdp[_usdp] = true; 41 | emit Added(_usdp); 42 | } 43 | 44 | function remove(address _usdp) external onlyManager { 45 | require(_usdp != address(0), 'Unit Protocol: ZERO_ADDRESS'); 46 | require(bridgedUsdp[_usdp], 'Unit Protocol: WAS_NOT_ADDED'); 47 | 48 | bridgedUsdp[_usdp] = false; 49 | emit Removed(_usdp); 50 | } 51 | 52 | // returns Q112-encoded value 53 | function assetToUsd(address asset, uint amount) public override view returns (uint) { 54 | require(bridgedUsdp[asset], 'Unit Protocol: TOKEN_IS_NOT_SUPPORTED'); 55 | return amount.mul(Q112); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /contracts/oracles/ChainlinkedKeydonixOracleMainAssetAbstract.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: bsl-1.1 2 | 3 | /* 4 | Copyright 2020 Unit Protocol: Artem Zakharov (az@unit.xyz). 5 | */ 6 | pragma solidity 0.7.6; 7 | 8 | import "./KeydonixOracleAbstract.sol"; 9 | pragma experimental ABIEncoderV2; 10 | 11 | 12 | /** 13 | * @title ChainlinkedKeydonixOracleMainAssetAbstract 14 | **/ 15 | abstract contract ChainlinkedKeydonixOracleMainAssetAbstract is KeydonixOracleAbstract { 16 | 17 | address public WETH; 18 | 19 | function assetToEth( 20 | address asset, 21 | uint amount, 22 | ProofDataStruct memory proofData 23 | ) public virtual view returns (uint); 24 | 25 | function ethToUsd(uint ethAmount) public virtual view returns (uint); 26 | } 27 | -------------------------------------------------------------------------------- /contracts/oracles/ChainlinkedKeydonixOraclePoolTokenAbstract.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: bsl-1.1 2 | 3 | /* 4 | Copyright 2020 Unit Protocol: Artem Zakharov (az@unit.xyz). 5 | */ 6 | pragma solidity 0.7.6; 7 | pragma experimental ABIEncoderV2; 8 | 9 | import "./ChainlinkedKeydonixOracleMainAssetAbstract.sol"; 10 | import "./KeydonixOracleAbstract.sol"; 11 | 12 | 13 | /** 14 | * @title ChainlinkedKeydonixOraclePoolTokenAbstract 15 | **/ 16 | abstract contract ChainlinkedKeydonixOraclePoolTokenAbstract is KeydonixOracleAbstract { 17 | 18 | ChainlinkedKeydonixOracleMainAssetAbstract public uniswapOracleMainAsset; 19 | } 20 | -------------------------------------------------------------------------------- /contracts/oracles/CurveLPOracle.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: bsl-1.1 2 | 3 | /* 4 | Copyright 2020 Unit Protocol: Artem Zakharov (az@unit.xyz). 5 | */ 6 | pragma solidity 0.7.6; 7 | 8 | import "../interfaces/IOracleUsd.sol"; 9 | import "../interfaces/IOracleEth.sol"; 10 | import "../helpers/ERC20Like.sol"; 11 | import "../helpers/SafeMath.sol"; 12 | import "../interfaces/IOracleRegistry.sol"; 13 | import "../interfaces/ICurveProvider.sol"; 14 | import "../interfaces/ICurveRegistry.sol"; 15 | import "../interfaces/ICurvePool.sol"; 16 | 17 | /** 18 | * @title CurveLPOracle 19 | * @dev Oracle to quote curve LP tokens 20 | **/ 21 | contract CurveLPOracle is IOracleUsd { 22 | using SafeMath for uint; 23 | 24 | uint public constant Q112 = 2 ** 112; 25 | uint public constant PRECISION = 1e18; 26 | 27 | // CurveProvider contract 28 | ICurveProvider public immutable curveProvider; 29 | // ChainlinkedOracle contract 30 | IOracleRegistry public immutable oracleRegistry; 31 | 32 | /** 33 | * @param _curveProvider The address of the Curve Provider. Mainnet: 0x0000000022D53366457F9d5E68Ec105046FC4383 34 | * @param _oracleRegistry The address of the OracleRegistry contract 35 | **/ 36 | constructor(address _curveProvider, address _oracleRegistry) { 37 | require(_curveProvider != address(0) && _oracleRegistry != address(0), "Unit Protocol: ZERO_ADDRESS"); 38 | curveProvider = ICurveProvider(_curveProvider); 39 | oracleRegistry = IOracleRegistry(_oracleRegistry); 40 | } 41 | 42 | // returns Q112-encoded value 43 | function assetToUsd(address asset, uint amount) public override view returns (uint) { 44 | if (amount == 0) return 0; 45 | ICurveRegistry cR = ICurveRegistry(curveProvider.get_registry()); 46 | ICurvePool cP = ICurvePool(cR.get_pool_from_lp_token(asset)); 47 | require(address(cP) != address(0), "Unit Protocol: NOT_A_CURVE_LP"); 48 | require(ERC20Like(asset).decimals() == uint8(18), "Unit Protocol: INCORRECT_DECIMALS"); 49 | 50 | uint coinsCount = cR.get_n_coins(address(cP))[0]; 51 | require(coinsCount != 0, "Unit Protocol: CURVE_INCORRECT_COINS_COUNT"); 52 | 53 | uint minCoinPrice_q112; 54 | 55 | for (uint i = 0; i < coinsCount; i++) { 56 | address _coin = cP.coins(i); 57 | address oracle = oracleRegistry.oracleByAsset(_coin); 58 | require(oracle != address(0), "Unit Protocol: ORACLE_NOT_FOUND"); 59 | uint _coinPrice_q112 = IOracleUsd(oracle).assetToUsd(_coin, 10 ** ERC20Like(_coin).decimals()) / 1 ether; 60 | if (i == 0 || _coinPrice_q112 < minCoinPrice_q112) { 61 | minCoinPrice_q112 = _coinPrice_q112; 62 | } 63 | } 64 | 65 | uint price_q112 = cP.get_virtual_price().mul(minCoinPrice_q112).div(PRECISION); 66 | 67 | return amount.mul(price_q112); 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /contracts/oracles/CyTokenOracle.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: bsl-1.1 2 | 3 | pragma solidity 0.7.6; 4 | 5 | import "../helpers/SafeMath.sol"; 6 | import "../helpers/ERC20Like.sol"; 7 | import "../interfaces/IcyToken.sol"; 8 | import "../interfaces/IOracleUsd.sol"; 9 | import "../interfaces/IOracleRegistry.sol"; 10 | import "../interfaces/IOracleEth.sol"; 11 | import "../VaultParameters.sol"; 12 | 13 | /** 14 | * @title CyTokenOracle 15 | * @dev Wrapper to quote cyToken assets like cyWETH, cyDAI, cyUSDT, cyUSDC 16 | * @dev cyToken list: https://docs.cream.finance/iron-bank/iron-bank#yearn-token-cytoken 17 | **/ 18 | 19 | contract CyTokenOracle is IOracleUsd, Auth { 20 | using SafeMath for uint; 21 | 22 | uint constant expScale = 1e18; 23 | 24 | mapping (address => bool) public enabledImplementations; 25 | 26 | IOracleRegistry public immutable oracleRegistry; 27 | 28 | event ImplementationChanged(address indexed implementation, bool enabled); 29 | 30 | constructor(address _vaultParameters, address _oracleRegistry, address[] memory impls) Auth(_vaultParameters) { 31 | require(_vaultParameters != address(0) && _oracleRegistry != address(0), "Unit Protocol: ZERO_ADDRESS"); 32 | oracleRegistry = IOracleRegistry(_oracleRegistry); 33 | for (uint i = 0; i < impls.length; i++) { 34 | require(impls[i] != address(0), "Unit Protocol: ZERO_ADDRESS"); 35 | enabledImplementations[impls[i]] = true; 36 | emit ImplementationChanged(impls[i], true); 37 | } 38 | } 39 | 40 | function setImplementation(address impl, bool enable) external onlyManager { 41 | require(impl != address(0), "Unit Protocol: ZERO_ADDRESS"); 42 | enabledImplementations[impl] = enable; 43 | emit ImplementationChanged(impl, enable); 44 | } 45 | 46 | // returns Q112-encoded value 47 | function assetToUsd(address bearing, uint amount) public override view returns (uint) { 48 | if (amount == 0) return 0; 49 | (address underlying, uint underlyingAmount) = bearingToUnderlying(bearing, amount); 50 | IOracleUsd _oracleForUnderlying = IOracleUsd(oracleRegistry.oracleByAsset(underlying)); 51 | require(address(_oracleForUnderlying) != address(0), "Unit Protocol: ORACLE_NOT_FOUND"); 52 | return _oracleForUnderlying.assetToUsd(underlying, underlyingAmount); 53 | } 54 | 55 | function bearingToUnderlying(address bearing, uint amount) public view returns (address, uint) { 56 | address _underlying = IcyToken(bearing).underlying(); 57 | require(_underlying != address(0), "Unit Protocol: UNDEFINED_UNDERLYING"); 58 | address _implementation = IcyToken(bearing).implementation(); 59 | require(enabledImplementations[_implementation], "Unit Protocol: UNSUPPORTED_CYTOKEN_IMPLEMENTATION"); 60 | uint _exchangeRateStored = IcyToken(bearing).exchangeRateStored(); 61 | uint _totalSupply = ERC20Like(bearing).totalSupply(); 62 | require(amount <= _totalSupply, "Unit Protocol: AMOUNT_EXCEEDS_SUPPLY"); 63 | return (_underlying, amount.mul(_exchangeRateStored).div(expScale)); 64 | } 65 | 66 | } 67 | -------------------------------------------------------------------------------- /contracts/oracles/KeydonixOracleAbstract.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: bsl-1.1 2 | 3 | /* 4 | Copyright 2020 Unit Protocol: Artem Zakharov (az@unit.xyz). 5 | */ 6 | pragma solidity 0.7.6; 7 | pragma experimental ABIEncoderV2; 8 | 9 | 10 | /** 11 | * @title KeydonixOracleAbstract 12 | **/ 13 | abstract contract KeydonixOracleAbstract { 14 | 15 | uint public constant Q112 = 2 ** 112; 16 | 17 | struct ProofDataStruct { 18 | bytes block; 19 | bytes accountProofNodesRlp; 20 | bytes reserveAndTimestampProofNodesRlp; 21 | bytes priceAccumulatorProofNodesRlp; 22 | } 23 | 24 | function assetToUsd( 25 | address asset, 26 | uint amount, 27 | ProofDataStruct memory proofData 28 | ) public virtual view returns (uint); 29 | } 30 | -------------------------------------------------------------------------------- /contracts/oracles/OracleSimple.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: bsl-1.1 2 | 3 | /* 4 | Copyright 2020 Unit Protocol: Artem Zakharov (az@unit.xyz). 5 | */ 6 | pragma solidity 0.7.6; 7 | 8 | 9 | /** 10 | * @title OracleSimple 11 | **/ 12 | abstract contract OracleSimple { 13 | function assetToUsd(address asset, uint amount) public virtual view returns (uint); 14 | } 15 | 16 | 17 | /** 18 | * @title OracleSimplePoolToken 19 | **/ 20 | abstract contract OracleSimplePoolToken is OracleSimple { 21 | ChainlinkedOracleSimple public oracleMainAsset; 22 | } 23 | 24 | 25 | /** 26 | * @title ChainlinkedOracleSimple 27 | **/ 28 | abstract contract ChainlinkedOracleSimple is OracleSimple { 29 | address public WETH; 30 | function ethToUsd(uint ethAmount) public virtual view returns (uint); 31 | function assetToEth(address asset, uint amount) public virtual view returns (uint); 32 | } 33 | -------------------------------------------------------------------------------- /contracts/oracles/WrappedToUnderlyingOracle.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: bsl-1.1 2 | 3 | /* 4 | Copyright 2020 Unit Protocol: Artem Zakharov (az@unit.xyz). 5 | */ 6 | pragma solidity 0.7.6; 7 | 8 | import "../helpers/ERC20Like.sol"; 9 | import "../VaultParameters.sol"; 10 | import "../interfaces/IOracleUsd.sol"; 11 | import "../interfaces/IOracleEth.sol"; 12 | import "../interfaces/IOracleRegistry.sol"; 13 | 14 | /** 15 | * @title WrappedToUnderlyingOracle 16 | * @dev Oracle to quote wrapped tokens to underlying 17 | **/ 18 | contract WrappedToUnderlyingOracle is IOracleUsd, Auth { 19 | 20 | IOracleRegistry public immutable oracleRegistry; 21 | 22 | mapping (address => address) public assetToUnderlying; 23 | 24 | event NewUnderlying(address indexed wrapped, address indexed underlying); 25 | 26 | constructor(address _vaultParameters, address _oracleRegistry) Auth(_vaultParameters) { 27 | require(_vaultParameters != address(0) && _oracleRegistry != address(0), "Unit Protocol: ZERO_ADDRESS"); 28 | oracleRegistry = IOracleRegistry(_oracleRegistry); 29 | } 30 | 31 | function setUnderlying(address wrapped, address underlying) external onlyManager { 32 | assetToUnderlying[wrapped] = underlying; 33 | emit NewUnderlying(wrapped, underlying); 34 | } 35 | 36 | // returns Q112-encoded value 37 | function assetToUsd(address asset, uint amount) public override view returns (uint) { 38 | if (amount == 0) return 0; 39 | 40 | (address oracle, address underlying) = _getOracleAndUnderlying(asset); 41 | 42 | return IOracleUsd(oracle).assetToUsd(underlying, amount); 43 | } 44 | 45 | function _getOracleAndUnderlying(address asset) internal view returns (address oracle, address underlying) { 46 | 47 | underlying = assetToUnderlying[asset]; 48 | require(underlying != address(0), "Unit Protocol: UNDEFINED_UNDERLYING"); 49 | 50 | oracle = oracleRegistry.oracleByAsset(underlying); 51 | require(oracle != address(0), "Unit Protocol: NO_ORACLE_FOUND"); 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /contracts/oracles/WrappedToUnderlyingOracleKeydonix.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: bsl-1.1 2 | 3 | /* 4 | Copyright 2021 Unit Protocol: Artem Zakharov (az@unit.xyz). 5 | */ 6 | pragma solidity 0.7.6; 7 | pragma experimental ABIEncoderV2; 8 | 9 | import "../interfaces/IOracleRegistry.sol"; 10 | import "./KeydonixOracleAbstract.sol"; 11 | import "../Auth2.sol"; 12 | 13 | /** 14 | * @title WrappedToUnderlyingOracleKeydonix 15 | * @dev Oracle to quote wrapped tokens to underlying 16 | **/ 17 | contract WrappedToUnderlyingOracleKeydonix is KeydonixOracleAbstract, Auth2 { 18 | 19 | IOracleRegistry public immutable oracleRegistry; 20 | 21 | mapping (address => address) public assetToUnderlying; 22 | 23 | event NewUnderlying(address indexed wrapped, address indexed underlying); 24 | 25 | constructor(address _vaultParameters, address _oracleRegistry) Auth2(_vaultParameters) { 26 | require(_oracleRegistry != address(0), "Unit Protocol: ZERO_ADDRESS"); 27 | oracleRegistry = IOracleRegistry(_oracleRegistry); 28 | } 29 | 30 | function setUnderlying(address wrapped, address underlying) external onlyManager { 31 | assetToUnderlying[wrapped] = underlying; 32 | emit NewUnderlying(wrapped, underlying); 33 | } 34 | 35 | // returns Q112-encoded value 36 | function assetToUsd( 37 | address asset, 38 | uint amount, 39 | ProofDataStruct memory proofData 40 | ) public override view returns (uint) { 41 | if (amount == 0) return 0; 42 | 43 | (address oracle, address underlying) = _getOracleAndUnderlying(asset); 44 | 45 | return KeydonixOracleAbstract(oracle).assetToUsd(underlying, amount, proofData); 46 | } 47 | 48 | /** 49 | * @dev for saving gas not checking underlying oracle for keydonix type since call to online oracle will fail anyway 50 | */ 51 | function _getOracleAndUnderlying(address asset) internal view returns (address oracle, address underlying) { 52 | underlying = assetToUnderlying[asset]; 53 | require(underlying != address(0), "Unit Protocol: UNDEFINED_UNDERLYING"); 54 | 55 | oracle = oracleRegistry.oracleByAsset(underlying); 56 | require(oracle != address(0), "Unit Protocol: NO_ORACLE_FOUND"); 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /contracts/oracles/YvTokenOracle.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: bsl-1.1 2 | 3 | pragma solidity 0.7.6; 4 | 5 | import "../helpers/SafeMath.sol"; 6 | import "../helpers/ERC20Like.sol"; 7 | import "../interfaces/IyvToken.sol"; 8 | import "../interfaces/IOracleUsd.sol"; 9 | import "../interfaces/IOracleRegistry.sol"; 10 | import "../interfaces/IOracleEth.sol"; 11 | import "../VaultParameters.sol"; 12 | 13 | /** 14 | * @title YvTokensOracle 15 | * @dev Wrapper to quote V2 yVault Tokens like yvWETH, yvDAI, yvUSDC, yvUSDT 16 | * @dev yVault Tokens list: https://docs.yearn.finance/yearn-finance/yvaults/vault-tokens#v2-yvault-tokens 17 | **/ 18 | 19 | contract YvTokenOracle is IOracleUsd, Auth { 20 | using SafeMath for uint; 21 | 22 | IOracleRegistry public immutable oracleRegistry; 23 | 24 | constructor(address _vaultParameters, address _oracleRegistry) Auth(_vaultParameters) { 25 | require(_vaultParameters != address(0) && _oracleRegistry != address(0), "Unit Protocol: ZERO_ADDRESS"); 26 | oracleRegistry = IOracleRegistry(_oracleRegistry); 27 | } 28 | 29 | // returns Q112-encoded value 30 | function assetToUsd(address bearing, uint amount) public override view returns (uint) { 31 | if (amount == 0) return 0; 32 | (address underlying, uint underlyingAmount) = bearingToUnderlying(bearing, amount); 33 | IOracleUsd _oracleForUnderlying = IOracleUsd(oracleRegistry.oracleByAsset(underlying)); 34 | require(address(_oracleForUnderlying) != address(0), "Unit Protocol: ORACLE_NOT_FOUND"); 35 | return _oracleForUnderlying.assetToUsd(underlying, underlyingAmount); 36 | } 37 | 38 | function bearingToUnderlying(address bearing, uint amount) public view returns (address, uint) { 39 | address _underlying = IyvToken(bearing).token(); 40 | require(_underlying != address(0), "Unit Protocol: UNDEFINED_UNDERLYING"); 41 | uint _totalSupply = ERC20Like(bearing).totalSupply(); 42 | require(amount <= _totalSupply, "Unit Protocol: AMOUNT_EXCEEDS_SUPPLY"); 43 | uint _pricePerShare = IyvToken(bearing).pricePerShare(); 44 | uint _decimals = IyvToken(bearing).decimals(); 45 | return (_underlying, amount.mul(_pricePerShare).div(10**_decimals)); 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /contracts/swappers/SwappersRegistry.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: bsl-1.1 2 | 3 | /* 4 | Copyright 2022 Unit Protocol: Artem Zakharov (az@unit.xyz). 5 | */ 6 | pragma solidity 0.7.6; 7 | 8 | import "../interfaces/swappers/ISwapper.sol"; 9 | import "../interfaces/swappers/ISwappersRegistry.sol"; 10 | import "../Auth2.sol"; 11 | 12 | 13 | contract SwappersRegistry is ISwappersRegistry, Auth2 { 14 | 15 | struct SwapperInfo { 16 | uint240 id; 17 | bool exists; 18 | } 19 | 20 | mapping(ISwapper => SwapperInfo) internal swappersInfo; 21 | ISwapper[] internal swappers; 22 | 23 | constructor(address _vaultParameters) Auth2(_vaultParameters) {} 24 | 25 | function getSwappersLength() external view override returns (uint) { 26 | return swappers.length; 27 | } 28 | 29 | function getSwapperId(ISwapper _swapper) external view override returns (uint) { 30 | require(hasSwapper(_swapper), "Unit Protocol Swappers: SWAPPER_IS_NOT_EXIST"); 31 | 32 | return uint(swappersInfo[_swapper].id); 33 | } 34 | 35 | function getSwapper(uint _id) external view override returns (ISwapper) { 36 | return swappers[_id]; 37 | } 38 | 39 | function hasSwapper(ISwapper _swapper) public view override returns (bool) { 40 | return swappersInfo[_swapper].exists; 41 | } 42 | 43 | function getSwappers() external view override returns (ISwapper[] memory) { 44 | return swappers; 45 | } 46 | 47 | function add(ISwapper _swapper) public onlyManager { 48 | require(address(_swapper) != address(0), "Unit Protocol Swappers: ZERO_ADDRESS"); 49 | require(!hasSwapper(_swapper), "Unit Protocol Swappers: SWAPPER_ALREADY_EXISTS"); 50 | 51 | swappers.push(_swapper); 52 | swappersInfo[_swapper] = SwapperInfo(uint240(swappers.length - 1), true); 53 | 54 | emit SwapperAdded(_swapper); 55 | } 56 | 57 | function remove(ISwapper _swapper) public onlyManager { 58 | require(address(_swapper) != address(0), "Unit Protocol Swappers: ZERO_ADDRESS"); 59 | require(hasSwapper(_swapper), "Unit Protocol Swappers: SWAPPER_IS_NOT_EXIST"); 60 | 61 | uint id = uint(swappersInfo[_swapper].id); 62 | delete swappersInfo[_swapper]; 63 | 64 | uint lastId = swappers.length - 1; 65 | if (id != lastId) { 66 | ISwapper lastSwapper = swappers[lastId]; 67 | swappers[id] = lastSwapper; 68 | swappersInfo[lastSwapper] = SwapperInfo(uint240(id), true); 69 | } 70 | swappers.pop(); 71 | 72 | emit SwapperRemoved(_swapper); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /contracts/swappers/helpers/CurveHelper.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: bsl-1.1 2 | 3 | /* 4 | Copyright 2022 Unit Protocol: Artem Zakharov (az@unit.xyz). 5 | */ 6 | pragma solidity 0.7.6; 7 | 8 | import "../../interfaces/ICurvePool.sol"; 9 | import "../../interfaces/curve/ICurvePoolMeta.sol"; 10 | 11 | library CurveHelper { 12 | 13 | int128 public constant MAX_COINS = 30; 14 | 15 | function getCoinIndexInMetaPool(ICurvePoolMeta _pool, address _coin) internal view returns (int128) { 16 | int128 basePoolIndex = 0; 17 | for (int128 i=0; i < MAX_COINS; i++) { 18 | address coin = tryGetCoin(_pool, i); 19 | if (coin == address(0)) { 20 | basePoolIndex = i - 1; 21 | break; 22 | } else if (_coin == coin) { 23 | return i; 24 | } 25 | } 26 | require(basePoolIndex > 0, "Unit Protocol Swappers: BROKEN_POOL"); // expected that base pool is the last 27 | 28 | int128 coinIndexInBasePool = getCoinIndexInPool(ICurvePool(_pool.base_pool()), _coin); 29 | require(coinIndexInBasePool >= 0, "Unit Protocol Swappers: BROKEN_POOL"); 30 | 31 | int128 coinIndex = coinIndexInBasePool + basePoolIndex; 32 | require(coinIndex >= coinIndexInBasePool, "Unit Protocol Swappers: BROKEN_POOL"); // assert from safe math since here we use int128 33 | 34 | return coinIndex; 35 | } 36 | 37 | function getCoinIndexInPool(ICurvePool _pool, address _coin) internal view returns (int128) { 38 | for (int128 i=0; i < MAX_COINS; i++) { 39 | address coin = tryGetCoin(_pool, i); 40 | if (coin == address(0)) { 41 | break; 42 | } else if (_coin == coin) { 43 | return i; 44 | } 45 | } 46 | 47 | revert("Unit Protocol Swappers: COIN_NOT_FOUND_IN_POOL"); 48 | } 49 | 50 | function tryGetCoin(ICurvePool _pool, int128 i) private view returns (address) { 51 | (bool success, bytes memory data) = address(_pool).staticcall{gas:20000}(abi.encodeWithSignature("coins(uint256)", uint(i))); 52 | if (!success || data.length != 32) { 53 | return address(0); 54 | } 55 | 56 | return bytesToAddress(data); 57 | } 58 | 59 | function bytesToAddress(bytes memory _bytes) private pure returns (address addr) { 60 | assembly { 61 | addr := mload(add(_bytes, 32)) 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /contracts/test-helpers/ChainlinkAggregator_Mock.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: bsl-1.1 2 | 3 | /* 4 | Copyright 2020 Unit Protocol: Artem Zakharov (az@unit.xyz). 5 | */ 6 | pragma solidity 0.7.6; 7 | 8 | contract ChainlinkAggregator_Mock { 9 | int public latestAnswer; 10 | uint public latestTimestamp = block.timestamp; 11 | uint public decimals; 12 | 13 | address admin = msg.sender; 14 | 15 | event AnswerUpdated(int256 indexed current, uint256 indexed roundId, uint256 timestamp); 16 | 17 | constructor (int price, uint _decimals) { 18 | latestAnswer = price; 19 | decimals = _decimals; 20 | } 21 | 22 | function setPrice(int price) external { 23 | require(msg.sender == admin, "Unit Protocol: UNAUTHORIZED"); 24 | latestAnswer = price; 25 | latestTimestamp = block.timestamp; 26 | emit AnswerUpdated(int(price), block.timestamp, block.timestamp); 27 | } 28 | 29 | function latestRoundData() 30 | external 31 | view 32 | returns ( 33 | uint80 roundId, 34 | int256 answer, 35 | uint256 startedAt, 36 | uint256 updatedAt, 37 | uint80 answeredInRound 38 | ) { 39 | answer = latestAnswer; 40 | updatedAt = latestTimestamp; 41 | 42 | roundId = 0; 43 | startedAt = 0; 44 | answeredInRound = 0; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /contracts/test-helpers/CurveMock.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: bsl-1.1 2 | 3 | /* 4 | Copyright 2020 Unit Protocol: Artem Zakharov (az@unit.xyz). 5 | */ 6 | pragma solidity 0.7.6; 7 | 8 | 9 | contract CurveProviderMock { 10 | 11 | address public immutable get_registry; 12 | 13 | constructor (address registry) { 14 | get_registry = registry; 15 | } 16 | } 17 | 18 | 19 | contract CurveRegistryMock { 20 | 21 | mapping (address => address) public get_pool_from_lp_token; 22 | mapping (address => uint[2]) _get_n_coins; 23 | 24 | constructor (address lp, address pool, uint nCoins) { 25 | setLP(lp, pool, nCoins); 26 | } 27 | 28 | function setLP(address lp, address pool, uint nCoins) public { 29 | get_pool_from_lp_token[lp] = pool; 30 | uint[2] memory nCoinsArray = [nCoins, nCoins]; 31 | _get_n_coins[pool] = nCoinsArray; 32 | } 33 | 34 | function get_n_coins(address pool) external view returns (uint[2] memory) { 35 | return _get_n_coins[pool]; 36 | } 37 | } 38 | 39 | 40 | contract CurvePool { 41 | 42 | uint public get_virtual_price; 43 | mapping (uint => address) public coins; 44 | 45 | function setPool(uint virtualPrice, address[] calldata _coins) public { 46 | get_virtual_price = virtualPrice; 47 | for (uint i = 0; i < _coins.length; i ++) { 48 | coins[i] = _coins[i]; 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /contracts/test-helpers/CyWETH.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: bsl-1.1 2 | 3 | /* 4 | Copyright 2020 Unit Protocol: Artem Zakharov (az@unit.xyz). 5 | */ 6 | pragma solidity 0.7.6; 7 | 8 | import "./EmptyToken.sol"; 9 | 10 | 11 | contract CyWETH is EmptyToken { 12 | 13 | address public underlying; 14 | 15 | address public implementation; 16 | 17 | uint public exchangeRateStoredInternal; 18 | 19 | constructor( 20 | uint _totalSupply, 21 | address _underlying, 22 | address _implementation, 23 | uint _exchangeRateStoredInternal 24 | ) EmptyToken( 25 | "Yearn Wrapped Ether", 26 | "cyWETH", 27 | 8, 28 | _totalSupply, 29 | msg.sender 30 | ) 31 | { 32 | underlying = _underlying; 33 | implementation = _implementation; 34 | exchangeRateStoredInternal = _exchangeRateStoredInternal; 35 | } 36 | 37 | function exchangeRateStored() public view returns (uint) { 38 | return exchangeRateStoredInternal; 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /contracts/test-helpers/DummyToken.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: bsl-1.1 2 | 3 | /* 4 | Copyright 2020 Unit Protocol: Artem Zakharov (az@unit.xyz). 5 | */ 6 | pragma solidity 0.7.6; 7 | 8 | import "./EmptyToken.sol"; 9 | 10 | 11 | contract DummyToken is EmptyToken { 12 | 13 | constructor( 14 | string memory _name, 15 | string memory _symbol, 16 | uint8 _decimals, 17 | uint _totalSupply 18 | ) EmptyToken( 19 | _name, 20 | _symbol, 21 | _decimals, 22 | _totalSupply, 23 | msg.sender 24 | ) 25 | {} 26 | } 27 | -------------------------------------------------------------------------------- /contracts/test-helpers/EmptyToken.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: bsl-1.1 2 | 3 | /* 4 | Copyright 2020 Unit Protocol: Artem Zakharov (az@unit.xyz). 5 | */ 6 | pragma solidity 0.7.6; 7 | 8 | import "./IAssetTestsMint.sol"; 9 | import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; 10 | 11 | contract EmptyToken is ERC20, IAssetTestsMint { 12 | using SafeMath for uint; 13 | 14 | event Burn(address indexed burner, uint value); 15 | 16 | function burn(uint _value) public returns (bool) { 17 | require(_value <= balanceOf(msg.sender), "BURN_INSUFFICIENT_BALANCE"); 18 | 19 | _burn(msg.sender, _value); 20 | return true; 21 | } 22 | 23 | function burnFrom(address _owner, uint _value) public returns (bool) { 24 | require(_owner != address(0), "ZERO_ADDRESS"); 25 | require(_value <= balanceOf(_owner), "BURNFROM_INSUFFICIENT_BALANCE"); 26 | require(_value <= allowance(_owner, msg.sender), "BURNFROM_INSUFFICIENT_ALLOWANCE"); 27 | 28 | _burn(_owner, _value); 29 | return true; 30 | } 31 | 32 | constructor( 33 | string memory _name, 34 | string memory _symbol, 35 | uint8 _decimals, 36 | uint _totalSupply, 37 | address _firstHolder 38 | ) ERC20(_name, _symbol) 39 | { 40 | require(_firstHolder != address(0), "ZERO_ADDRESS"); 41 | checkSymbolAndName(_symbol,_name); 42 | 43 | _setupDecimals(_decimals); 44 | 45 | _mint(_firstHolder, _totalSupply); 46 | } 47 | 48 | // Make sure symbol has 3-8 chars in [A-Za-z._] and name has up to 128 chars. 49 | function checkSymbolAndName( 50 | string memory _symbol, 51 | string memory _name 52 | ) 53 | internal 54 | pure 55 | { 56 | bytes memory s = bytes(_symbol); 57 | require(s.length >= 3 && s.length <= 8, "INVALID_SIZE"); 58 | for (uint i = 0; i < s.length; i++) { 59 | // make sure symbol contains only [A-Za-z._] 60 | require( 61 | s[i] == 0x2E || ( 62 | s[i] == 0x5F) || ( 63 | s[i] >= 0x41 && s[i] <= 0x5A) || ( 64 | s[i] >= 0x61 && s[i] <= 0x7A), "INVALID_VALUE"); 65 | } 66 | bytes memory n = bytes(_name); 67 | require(n.length >= s.length && n.length <= 128, "INVALID_SIZE"); 68 | for (uint i = 0; i < n.length; i++) { 69 | require(n[i] >= 0x20 && n[i] <= 0x7E, "INVALID_VALUE"); 70 | } 71 | } 72 | 73 | function tests_mint(address to, uint amount) public override { 74 | _mint(to, amount); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /contracts/test-helpers/FoundationMock.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: bsl-1.1 2 | 3 | /* 4 | Copyright 2020 Unit Protocol: Artem Zakharov (az@unit.xyz). 5 | */ 6 | pragma solidity 0.7.6; 7 | 8 | import "../interfaces/IFoundation.sol"; 9 | 10 | 11 | contract FoundationMock is IFoundation { 12 | function submitLiquidationFee(uint fee) external override {} 13 | } 14 | -------------------------------------------------------------------------------- /contracts/test-helpers/IAssetTestsMint.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: bsl-1.1 2 | 3 | /* 4 | Copyright 2022 Unit Protocol: Artem Zakharov (az@unit.xyz). 5 | */ 6 | pragma solidity ^0.7.6; 7 | 8 | interface IAssetTestsMint { 9 | function tests_mint(address _user, uint _amount) external; 10 | } 11 | -------------------------------------------------------------------------------- /contracts/test-helpers/KeydonixOraclePoolToken_Mock.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: bsl-1.1 2 | 3 | /* 4 | Copyright 2020 Unit Protocol: Artem Zakharov (az@unit.xyz). 5 | */ 6 | pragma solidity 0.7.6; 7 | pragma experimental ABIEncoderV2; 8 | 9 | import "../oracles/ChainlinkedKeydonixOracleMainAssetAbstract.sol"; 10 | import "../oracles/ChainlinkedKeydonixOraclePoolTokenAbstract.sol"; 11 | import "../helpers/IUniswapV2PairFull.sol"; 12 | import "../helpers/SafeMath.sol"; 13 | 14 | /** 15 | * @title KeydonixOraclePoolToken_Mock 16 | * @dev Calculates the USD price of desired tokens 17 | **/ 18 | contract KeydonixOraclePoolToken_Mock is ChainlinkedKeydonixOraclePoolTokenAbstract { 19 | using SafeMath for uint; 20 | 21 | constructor(address _keydonixOracleMainAsset_Mock) { 22 | uniswapOracleMainAsset = ChainlinkedKeydonixOracleMainAssetAbstract(_keydonixOracleMainAsset_Mock); 23 | } 24 | 25 | // override with mock; only for tests 26 | function assetToUsd(address asset, uint amount, ProofDataStruct memory /* proofData */) public override view returns (uint) { 27 | 28 | IUniswapV2PairFull pair = IUniswapV2PairFull(asset); 29 | 30 | uint ePool; // current WETH pool 31 | 32 | (uint112 _reserve0, uint112 _reserve1,) = pair.getReserves(); 33 | 34 | if (pair.token0() == uniswapOracleMainAsset.WETH()) { 35 | ePool = _reserve0; 36 | } else if (pair.token1() == uniswapOracleMainAsset.WETH()) { 37 | ePool = _reserve1; 38 | } else { 39 | revert("Unit Protocol: NOT_REGISTERED_PAIR"); 40 | } 41 | 42 | uint totalValueInEth_q112 = amount.mul(ePool).mul(2).mul(Q112).div(pair.totalSupply()); 43 | 44 | return uniswapOracleMainAsset.ethToUsd(totalValueInEth_q112); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /contracts/test-helpers/KeydonixSimpleOracle_Mock.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: bsl-1.1 2 | 3 | /* 4 | Copyright 2022 Unit Protocol: Artem Zakharov (az@unit.xyz). 5 | */ 6 | pragma solidity 0.7.6; 7 | pragma experimental ABIEncoderV2; 8 | 9 | import "../oracles/KeydonixOracleAbstract.sol"; 10 | 11 | /** 12 | * @title KeydonixSimpleOracle_Mock 13 | * @dev Used in tests 14 | **/ 15 | contract KeydonixSimpleOracle_Mock is KeydonixOracleAbstract { 16 | 17 | uint public rate = 1234; 18 | 19 | function setRate(uint _rate) public { 20 | rate = _rate; 21 | } 22 | 23 | function assetToUsd(address /* asset */, uint amount, ProofDataStruct memory proofData) public override view returns (uint) { 24 | require(keccak256(proofData.block) == keccak256(hex"01"), "Unit Protocol: proofData.block"); 25 | require(keccak256(proofData.accountProofNodesRlp) == keccak256(hex"02"), "Unit Protocol: proofData.accountProofNodesRlp"); 26 | require(keccak256(proofData.reserveAndTimestampProofNodesRlp) == keccak256(hex"03"), "Unit Protocol: proofData.reserveAndTimestampProofNodesRlp"); 27 | require(keccak256(proofData.priceAccumulatorProofNodesRlp) == keccak256(hex"04"), "Unit Protocol: proofData.priceAccumulatorProofNodesRlp"); 28 | 29 | return amount * rate; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /contracts/test-helpers/SimpleOracle_Mock.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: bsl-1.1 2 | 3 | /* 4 | Copyright 2022 Unit Protocol: Artem Zakharov (az@unit.xyz). 5 | */ 6 | pragma solidity 0.7.6; 7 | pragma experimental ABIEncoderV2; 8 | 9 | import "../interfaces/IOracleUsd.sol"; 10 | 11 | /** 12 | * @title SimpleOracle_Mock 13 | * @dev Used in tests 14 | **/ 15 | contract SimpleOracle_Mock is IOracleUsd { 16 | 17 | function assetToUsd(address /* asset */, uint amount) public override pure returns (uint) { 18 | return amount * 1234; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /contracts/test-helpers/StETH.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: bsl-1.1 2 | 3 | /* 4 | Copyright 2021 Unit Protocol: Artem Zakharov (az@unit.xyz). 5 | */ 6 | 7 | pragma solidity 0.7.6; 8 | 9 | import "./EmptyToken.sol"; 10 | import "../interfaces/IStETH.sol"; 11 | 12 | contract StETH is IStETH, EmptyToken { 13 | using SafeMath for uint; 14 | 15 | uint256 public totalPooledEther; 16 | bytes32 internal constant TOTAL_SHARES_POSITION = keccak256("lido.StETH.totalShares"); 17 | 18 | constructor( 19 | uint256 _totalPooledEther, 20 | uint256 _totalShares 21 | ) EmptyToken( 22 | "Liquid staked Ether 2.0", 23 | "stETH", 24 | 18, 25 | _totalShares, 26 | msg.sender 27 | ) { 28 | totalPooledEther = _totalPooledEther; 29 | _mintShares(_totalShares); 30 | } 31 | 32 | function setStorageUint256(bytes32 position, uint256 data) internal { 33 | assembly { sstore(position, data) } 34 | } 35 | 36 | function _mintShares(uint256 _sharesAmount) internal returns (uint256 newTotalShares) { 37 | newTotalShares = _getTotalShares().add(_sharesAmount); 38 | setStorageUint256(TOTAL_SHARES_POSITION, newTotalShares); 39 | } 40 | 41 | function getStorageUint256(bytes32 position) internal view returns (uint256 data) { 42 | assembly { data := sload(position) } 43 | } 44 | 45 | function _getTotalShares() internal view returns (uint256) { 46 | return getStorageUint256(TOTAL_SHARES_POSITION); 47 | } 48 | 49 | function _getTotalPooledEther() internal view returns (uint256) { 50 | return totalPooledEther; 51 | } 52 | 53 | function getPooledEthByShares(uint256 _sharesAmount) public override view returns (uint256) { 54 | uint256 totalShares = _getTotalShares(); 55 | if (totalShares == 0) { 56 | return 0; 57 | } else { 58 | return _sharesAmount 59 | .mul(_getTotalPooledEther()) 60 | .div(totalShares); 61 | } 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /contracts/test-helpers/StETHCurvePool.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: bsl-1.1 2 | 3 | /* 4 | Copyright 2021 Unit Protocol: Artem Zakharov (az@unit.xyz). 5 | */ 6 | 7 | pragma solidity 0.7.6; 8 | 9 | import "../interfaces/IStableSwap.sol"; 10 | 11 | contract StETHCurvePool is IStableSwap { 12 | 13 | uint256 public price; 14 | 15 | uint256 public constant CURVE_STETH_INDEX = 0; 16 | uint256 public constant CURVE_ETH_INDEX = 1; 17 | 18 | constructor(uint256 _price) { 19 | price = _price; 20 | } 21 | 22 | function get_dy(uint256 x, uint256 y, uint256 dx) public override view returns (uint256) { 23 | require(x == CURVE_STETH_INDEX && y == CURVE_ETH_INDEX && dx == 10**18,'CHECK_INCOME_VARIABLES_FAILED'); 24 | return price; 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /contracts/test-helpers/StETHPriceFeed.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: bsl-1.1 2 | 3 | /* 4 | Copyright 2021 Unit Protocol: Artem Zakharov (az@unit.xyz). 5 | */ 6 | 7 | pragma solidity ^0.7.6; 8 | 9 | import "../interfaces/IStableSwap.sol"; 10 | import "../interfaces/IStableSwapStateOracle.sol"; 11 | 12 | contract StETHPriceFeed { 13 | 14 | address public curve_pool_address; 15 | address public stable_swap_oracle_address; 16 | uint256 public constant CURVE_STETH_INDEX = 0; 17 | uint256 public constant CURVE_ETH_INDEX = 1; 18 | 19 | // Maximal difference accepted is 10% (1000) 20 | uint256 public constant max_safe_price_difference = 1000; 21 | 22 | constructor( 23 | address _curve_pool_address, 24 | address _stable_swap_oracle_address 25 | ) { 26 | curve_pool_address = _curve_pool_address; 27 | stable_swap_oracle_address = _stable_swap_oracle_address; 28 | } 29 | 30 | function _percentage_diff(uint256 newVal, uint256 oldVal) internal pure returns (uint256) { 31 | if (newVal > oldVal) { 32 | return (newVal - oldVal) * 10000 / oldVal; 33 | } else { 34 | return (oldVal - newVal) * 10000 / oldVal; 35 | } 36 | } 37 | 38 | function _current_price() internal view returns (uint256 pool_price, bool has_changed_unsafely, uint256 oracle_price) { 39 | pool_price = IStableSwap(curve_pool_address).get_dy(CURVE_STETH_INDEX, CURVE_ETH_INDEX, 10**18); 40 | oracle_price = IStableSwapStateOracle(stable_swap_oracle_address).stethPrice(); 41 | has_changed_unsafely = _percentage_diff(pool_price, oracle_price) > max_safe_price_difference; 42 | } 43 | 44 | function current_price() public view returns (uint256, bool) { 45 | uint256 currentPrice = 0; 46 | bool has_changed_unsafely = true; 47 | uint256 oracle_price = 0; 48 | (currentPrice, has_changed_unsafely, oracle_price) = _current_price(); 49 | bool is_safe = currentPrice <= 10**18 && !has_changed_unsafely; 50 | return (currentPrice, is_safe); 51 | } 52 | 53 | function full_price_info() public view returns (uint256, bool, uint256) { 54 | uint256 currentPrice = 0; 55 | bool has_changed_unsafely = true; 56 | uint256 oracle_price = 0; 57 | (currentPrice, has_changed_unsafely, oracle_price) = _current_price(); 58 | bool is_safe = currentPrice <= 10**18 && !has_changed_unsafely; 59 | return (currentPrice, is_safe, oracle_price); 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /contracts/test-helpers/StETHStableSwapOracle.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: bsl-1.1 2 | 3 | /* 4 | Copyright 2021 Unit Protocol: Artem Zakharov (az@unit.xyz). 5 | */ 6 | 7 | pragma solidity 0.7.6; 8 | 9 | import "../interfaces/IStableSwapStateOracle.sol"; 10 | 11 | contract StETHStableSwapOracle is IStableSwapStateOracle { 12 | 13 | uint256 public price; 14 | 15 | constructor(uint256 _price) { 16 | price = _price; 17 | } 18 | 19 | function stethPrice() public override view returns (uint256) { 20 | return price; 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /contracts/test-helpers/SwapperMock.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: bsl-1.1 2 | 3 | /* 4 | Copyright 2022 Unit Protocol: Artem Zakharov (az@unit.xyz). 5 | */ 6 | pragma solidity 0.7.6; 7 | 8 | import "../interfaces/swappers/ISwapper.sol"; 9 | import "./IAssetTestsMint.sol"; 10 | import "../helpers/TransferHelper.sol"; 11 | 12 | /** 13 | * @title SwapperMock 14 | * @dev Used in tests 15 | **/ 16 | contract SwapperMock is ISwapper { 17 | 18 | uint public assetToUsdpRate = 1; 19 | address public immutable USDP; 20 | 21 | constructor(address _usdp) { 22 | USDP = _usdp; 23 | } 24 | 25 | function tests_setAssetToUsdpRate(uint _rate) public { 26 | assetToUsdpRate = _rate; 27 | } 28 | 29 | function predictAssetOut(address /* _asset */, uint256 _usdpAmountIn) external view override returns (uint predictedAssetAmount) { 30 | return _usdpAmountIn / assetToUsdpRate; 31 | } 32 | 33 | function predictUsdpOut(address /* _asset */, uint256 _assetAmountIn) external view override returns (uint predictedUsdpAmount) { 34 | return _assetAmountIn * assetToUsdpRate; 35 | } 36 | 37 | function swapUsdpToAsset(address _user, address _asset, uint256 _usdpAmount, uint256 _minAssetAmount) external override returns (uint swappedAssetAmount) { 38 | require(_minAssetAmount == _usdpAmount / assetToUsdpRate); // in _minAssetAmount we must send result of prediction. In tests the same 39 | TransferHelper.safeTransferFrom(USDP, _user, address(this), _usdpAmount); 40 | IAssetTestsMint(_asset).tests_mint(_user, _minAssetAmount); 41 | return _minAssetAmount; 42 | } 43 | 44 | function swapAssetToUsdp(address _user, address _asset, uint256 _assetAmount, uint256 _minUsdpAmount) external override returns (uint swappedUsdpAmount) { 45 | require(_minUsdpAmount == _assetAmount * assetToUsdpRate); // in _minAssetAmount we must send result of prediction. In tests the same 46 | TransferHelper.safeTransferFrom(_asset, _user, address(this), _assetAmount); 47 | IAssetTestsMint(USDP).tests_mint(_user, _minUsdpAmount); 48 | return _minUsdpAmount; 49 | } 50 | 51 | function swapUsdpToAssetWithDirectSending(address _user, address _asset, uint256 _usdpAmount, uint256 _minAssetAmount) external override returns (uint swappedAssetAmount) { 52 | require(_minAssetAmount == _usdpAmount / assetToUsdpRate); // in _minAssetAmount we must send result of prediction. In tests the same 53 | IAssetTestsMint(_asset).tests_mint(_user, _minAssetAmount); 54 | return _minAssetAmount; 55 | } 56 | 57 | function swapAssetToUsdpWithDirectSending(address _user, address /* _asset */, uint256 _assetAmount, uint256 _minUsdpAmount) external override returns (uint swappedUsdpAmount) { 58 | require(_minUsdpAmount == _assetAmount * assetToUsdpRate); // in _minAssetAmount we must send result of prediction. In tests the same 59 | IAssetTestsMint(USDP).tests_mint(_user, _minUsdpAmount); 60 | return _minUsdpAmount; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /contracts/test-helpers/USDPMock.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: bsl-1.1 2 | 3 | /* 4 | Copyright 2020 Unit Protocol: Artem Zakharov (az@unit.xyz). 5 | */ 6 | pragma solidity 0.7.6; 7 | 8 | import "../USDP.sol"; 9 | import "./IAssetTestsMint.sol"; 10 | 11 | 12 | contract USDPMock is USDP, IAssetTestsMint { 13 | using SafeMath for uint; 14 | 15 | constructor(address _parameters) USDP(_parameters) {} 16 | 17 | function tests_mint(address to, uint amount) public override { 18 | require(to != address(0), "Unit Protocol: ZERO_ADDRESS"); 19 | 20 | balanceOf[to] = balanceOf[to].add(amount); 21 | totalSupply = totalSupply.add(amount); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /contracts/test-helpers/WETHMock.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: bsl-1.1 2 | 3 | /* 4 | Copyright 2020 Unit Protocol: Artem Zakharov (az@unit.xyz). 5 | */ 6 | pragma solidity 0.7.6; 7 | 8 | import "./IAssetTestsMint.sol"; 9 | import "../interfaces/IWETH.sol"; 10 | import "../helpers/SafeMath.sol"; 11 | 12 | contract WETHMock is IWETH, IAssetTestsMint { 13 | using SafeMath for uint; 14 | 15 | string public name = "Wrapped Ether"; 16 | string public symbol = "WETH"; 17 | uint8 public decimals = 18; 18 | 19 | event Approval(address indexed src, address indexed guy, uint wad); 20 | event Transfer(address indexed src, address indexed dst, uint wad); 21 | event Deposit(address indexed dst, uint wad); 22 | event Withdrawal(address indexed src, uint wad); 23 | 24 | mapping (address => uint) public balanceOf; 25 | mapping (address => mapping (address => uint)) public allowance; 26 | 27 | uint testsMinted = 0; 28 | 29 | receive() external payable { 30 | deposit(); 31 | } 32 | function deposit() public override payable { 33 | balanceOf[msg.sender] += msg.value; 34 | emit Deposit(msg.sender, msg.value); 35 | } 36 | function withdraw(uint wad) public override { 37 | require(balanceOf[msg.sender] >= wad); 38 | balanceOf[msg.sender] -= wad; 39 | msg.sender.transfer(wad); 40 | emit Withdrawal(msg.sender, wad); 41 | } 42 | 43 | function totalSupply() public view returns (uint) { 44 | return address(this).balance + testsMinted; 45 | } 46 | 47 | function approve(address guy, uint wad) public returns (bool) { 48 | allowance[msg.sender][guy] = wad; 49 | Approval(msg.sender, guy, wad); 50 | return true; 51 | } 52 | 53 | function transfer(address dst, uint wad) public override returns (bool) { 54 | return transferFrom(msg.sender, dst, wad); 55 | } 56 | 57 | function transferFrom(address src, address dst, uint wad) 58 | public override 59 | returns (bool) 60 | { 61 | require(balanceOf[src] >= wad); 62 | 63 | if (src != msg.sender && allowance[src][msg.sender] != uint(-1)) { 64 | require(allowance[src][msg.sender] >= wad); 65 | allowance[src][msg.sender] -= wad; 66 | } 67 | 68 | balanceOf[src] -= wad; 69 | balanceOf[dst] += wad; 70 | 71 | Transfer(src, dst, wad); 72 | 73 | return true; 74 | } 75 | 76 | function tests_mint(address to, uint amount) public override { 77 | require(to != address(0), "Unit Protocol: ZERO_ADDRESS"); 78 | 79 | balanceOf[to] = balanceOf[to].add(amount); 80 | testsMinted = testsMinted.add(amount); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /contracts/test-helpers/WrappedAssetMock.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: bsl-1.1 2 | 3 | /* 4 | Copyright 2022 Unit Protocol: Artem Zakharov (az@unit.xyz). 5 | */ 6 | pragma solidity 0.7.6; 7 | 8 | import "../helpers/TransferHelper.sol"; 9 | import "../interfaces/wrapped-assets/IWrappedAsset.sol"; 10 | 11 | import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; 12 | 13 | /** 14 | * @title SwapperMock 15 | * @dev Used in tests 16 | **/ 17 | contract WrappedAssetMock is ERC20, IWrappedAsset { 18 | 19 | address public underlyingToken; 20 | bytes32 public constant override isUnitProtocolWrappedAsset = keccak256("UnitProtocolWrappedAsset"); 21 | 22 | constructor(address _underlyingToken) ERC20('TestsWA', 'Tests wrapped asset') { 23 | underlyingToken = _underlyingToken; 24 | } 25 | 26 | function getUnderlyingToken() external view override returns (IERC20) { 27 | return IERC20(underlyingToken); 28 | } 29 | 30 | function setUnderlyingToken(address _underlyingToken) external { 31 | underlyingToken = _underlyingToken; 32 | } 33 | 34 | /** 35 | * @notice deposit underlying token and send wrapped token to user 36 | * @dev Important! Only user or trusted contracts must be able to call this method 37 | */ 38 | function deposit(address _userAddr, uint256 _amount) external override { 39 | // no caller check since it is for tests only 40 | TransferHelper.safeTransferFrom(underlyingToken, _userAddr, address(this), _amount); 41 | _mint(_userAddr, _amount); 42 | } 43 | 44 | /** 45 | * @notice get wrapped token and return underlying 46 | * @dev Important! Only user or trusted contracts must be able to call this method 47 | */ 48 | function withdraw(address _userAddr, uint256 _amount) external override { 49 | // no caller check since it is for tests only 50 | _burn(_userAddr, _amount); 51 | TransferHelper.safeTransfer(underlyingToken, _userAddr, _amount); 52 | } 53 | 54 | /** 55 | * @notice get pending reward amount for user if reward is supported 56 | */ 57 | function pendingReward(address /** _userAddr */) external pure override returns (uint256) { 58 | return 0; 59 | } 60 | 61 | /** 62 | * @notice claim pending reward for user if reward is supported 63 | */ 64 | function claimReward(address /** _userAddr */) external override {} 65 | 66 | /** 67 | * @notice Manually move position (or its part) to another user (for example in case of liquidation) 68 | * @dev Important! Only trusted contracts must be able to call this method 69 | */ 70 | function movePosition(address /** _userAddrFrom */, address /** _userAddrTo */, uint256 /** _amount */) external override {} 71 | } 72 | -------------------------------------------------------------------------------- /contracts/test-helpers/WstETH.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: bsl-1.1 2 | 3 | /* 4 | Copyright 2021 Unit Protocol: Artem Zakharov (az@unit.xyz). 5 | */ 6 | 7 | pragma solidity 0.7.6; 8 | 9 | import "./EmptyToken.sol"; 10 | import "../interfaces/IWstEthToken.sol"; 11 | import "../interfaces/IStETH.sol"; 12 | 13 | contract WstETH is EmptyToken, IWstEthToken { 14 | 15 | address public stETHAddr; 16 | 17 | constructor( 18 | uint256 _totalSupply, 19 | address _stEth 20 | ) EmptyToken( 21 | "Wrapped liquid staked Ether 2.0", 22 | "wstETH", 23 | 18, 24 | _totalSupply, 25 | msg.sender 26 | ) { 27 | stETHAddr = _stEth; 28 | } 29 | 30 | function getStETHByWstETH(uint256 _wstETHAmount) public override view returns (uint256) { 31 | return IStETH(stETHAddr).getPooledEthByShares(_wstETHAmount); 32 | } 33 | 34 | function stETH() public override view returns (address) { 35 | return stETHAddr; 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /contracts/test-helpers/YvWETH.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: bsl-1.1 2 | 3 | /* 4 | Copyright 2020 Unit Protocol: Artem Zakharov (az@unit.xyz). 5 | */ 6 | pragma solidity 0.7.6; 7 | 8 | import "./EmptyToken.sol"; 9 | 10 | 11 | contract YvWETH is EmptyToken { 12 | 13 | address public token; 14 | 15 | uint256 public pricePerShare; 16 | 17 | 18 | constructor( 19 | uint256 _totalSupply, 20 | address _token, 21 | uint256 _pricePerShare 22 | ) EmptyToken( 23 | "WETH yVault", 24 | "yvWETH", 25 | 18, 26 | _totalSupply, 27 | msg.sender 28 | ) { 29 | token = _token; 30 | pricePerShare = _pricePerShare; 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /contracts/vault-managers/parameters/AssetParameters.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: bsl-1.1 2 | 3 | /* 4 | Copyright 2021 Unit Protocol: Artem Zakharov (az@unit.xyz). 5 | */ 6 | pragma solidity 0.7.6; 7 | 8 | /** 9 | * @title AssetParameters 10 | **/ 11 | library AssetParameters { 12 | 13 | /** 14 | * Some assets require a transfer of at least 1 unit of token 15 | * to update internal logic related to staking rewards in case of full liquidation 16 | */ 17 | uint8 public constant PARAM_FORCE_TRANSFER_ASSET_TO_OWNER_ON_LIQUIDATION = 0; 18 | 19 | /** 20 | * Some wrapped assets that require a manual position transfer between users 21 | * since `transfer` doesn't do this 22 | */ 23 | uint8 public constant PARAM_FORCE_MOVE_WRAPPED_ASSET_POSITION_ON_LIQUIDATION = 1; 24 | 25 | function needForceTransferAssetToOwnerOnLiquidation(uint256 assetBoolParams) internal pure returns (bool) { 26 | return assetBoolParams & (1 << PARAM_FORCE_TRANSFER_ASSET_TO_OWNER_ON_LIQUIDATION) != 0; 27 | } 28 | 29 | function needForceMoveWrappedAssetPositionOnLiquidation(uint256 assetBoolParams) internal pure returns (bool) { 30 | return assetBoolParams & (1 << PARAM_FORCE_MOVE_WRAPPED_ASSET_POSITION_ON_LIQUIDATION) != 0; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /contracts/vault-managers/parameters/AssetsBooleanParameters.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: bsl-1.1 2 | 3 | /* 4 | Copyright 2021 Unit Protocol: Artem Zakharov (az@unit.xyz). 5 | */ 6 | pragma solidity 0.7.6; 7 | 8 | import "../../Auth2.sol"; 9 | import "../../interfaces/vault-managers/parameters/IAssetsBooleanParameters.sol"; 10 | 11 | 12 | /** 13 | * @title AssetsBooleanParameters 14 | **/ 15 | contract AssetsBooleanParameters is Auth2, IAssetsBooleanParameters { 16 | 17 | mapping(address => uint256) internal values; 18 | 19 | constructor(address _vaultParameters, address[] memory _initialAssets, uint8[] memory _initialParams) Auth2(_vaultParameters) { 20 | require(_initialAssets.length == _initialParams.length, "Unit Protocol: ARGUMENTS_LENGTH_MISMATCH"); 21 | 22 | for (uint i = 0; i < _initialAssets.length; i++) { 23 | _set(_initialAssets[i], _initialParams[i], true); 24 | } 25 | } 26 | 27 | /** 28 | * @notice Get value of _param for _asset 29 | * @dev see ParametersConstants 30 | **/ 31 | function get(address _asset, uint8 _param) external override view returns (bool) { 32 | return values[_asset] & (1 << _param) != 0; 33 | } 34 | 35 | /** 36 | * @notice Get values of all params for _asset. The 0th bit of returned uint id the value of param=0, etc 37 | **/ 38 | function getAll(address _asset) external override view returns (uint256) { 39 | return values[_asset]; 40 | } 41 | 42 | /** 43 | * @notice Set value of _param for _asset 44 | * @dev see ParametersConstants 45 | **/ 46 | function set(address _asset, uint8 _param, bool _value) public override onlyManager { 47 | _set(_asset, _param, _value); 48 | } 49 | 50 | function _set(address _asset, uint8 _param, bool _value) internal { 51 | require(_asset != address(0), "Unit Protocol: ZERO_ADDRESS"); 52 | 53 | if (_value) { 54 | values[_asset] |= (1 << _param); 55 | emit ValueSet(_asset, _param, values[_asset]); 56 | } else { 57 | values[_asset] &= ~(1 << _param); 58 | emit ValueUnset(_asset, _param, values[_asset]); 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /contracts/wrapped-assets/test-helpers/BoneToken_Mock.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | // Origin Shiba contracts slightly changed for run in tests 3 | 4 | pragma solidity 0.7.6; 5 | 6 | import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; 7 | import "@openzeppelin/contracts/access/Ownable.sol"; 8 | 9 | import "../../interfaces/wrapped-assets/IBoneToken.sol"; 10 | 11 | 12 | // BoneToken with Governance. 13 | contract BoneToken_Mock is IBoneToken, ERC20("BONE SHIBASWAP", "BONE"), Ownable { 14 | using SafeMath for uint256; 15 | /// @notice Creates `_amount` token to `_to`. Must only be called by the owner (TopDog). 16 | function mint(address _to, uint256 _amount) public override onlyOwner { 17 | _mint(_to, _amount); 18 | } 19 | 20 | function testMint(address _to, uint256 _amount) public { 21 | _mint(_to, _amount); 22 | } 23 | } -------------------------------------------------------------------------------- /contracts/wrapped-assets/test-helpers/MigratorShib_Mock.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: bsl-1.1 2 | 3 | /* 4 | Copyright 2021 Unit Protocol: Artem Zakharov (az@unit.xyz). 5 | */ 6 | pragma solidity 0.7.6; 7 | 8 | import "./TopDog_Mock.sol"; 9 | 10 | 11 | contract MigratorShib_Mock is IMigratorShib { 12 | 13 | IERC20 public newToken; 14 | 15 | function migrate(IERC20 token) external override returns (IERC20) { 16 | newToken.transfer(msg.sender, token.balanceOf(msg.sender)); 17 | return newToken; 18 | } 19 | 20 | function setNewToken(IERC20 token) public { 21 | newToken = token; 22 | } 23 | } -------------------------------------------------------------------------------- /contracts/wrapped-assets/test-helpers/SushiSwapLpToken_Mock.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: bsl-1.1 2 | 3 | /* 4 | Copyright 2021 Unit Protocol: Artem Zakharov (az@unit.xyz). 5 | */ 6 | pragma solidity 0.7.6; 7 | 8 | import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; 9 | 10 | import "../../interfaces/wrapped-assets/ISushiSwapLpToken.sol"; 11 | 12 | 13 | contract SushiSwapLpToken_Mock is ERC20, ISushiSwapLpToken { 14 | address public override token0; 15 | address public override token1; 16 | 17 | constructor (address _token0, address _token1, string memory name_, string memory symbol_, uint8 decimals_) 18 | ERC20(name_, symbol_) 19 | { 20 | token0 = _token0; 21 | token1 = _token1; 22 | 23 | _setupDecimals(decimals_); 24 | _mint(msg.sender, 100 ether); 25 | } 26 | } -------------------------------------------------------------------------------- /doc/dev-full/AbstractSwapper.md: -------------------------------------------------------------------------------- 1 | # Solidity API 2 | 3 | ## AbstractSwapper 4 | 5 | _base class for swappers, makes common checks 6 | internal _swapUsdpToAsset and _swapAssetToUsdp must be overridden instead of external swapUsdpToAsset and swapAssetToUsdp_ 7 | 8 | ### USDP 9 | 10 | ```solidity 11 | contract IERC20 USDP 12 | ``` 13 | 14 | ### constructor 15 | 16 | ```solidity 17 | constructor(address _vaultParameters, address _usdp) internal 18 | ``` 19 | 20 | ### _swapUsdpToAsset 21 | 22 | ```solidity 23 | function _swapUsdpToAsset(address _user, address _asset, uint256 _usdpAmount, uint256 _minAssetAmount) internal virtual returns (uint256 swappedAssetAmount) 24 | ``` 25 | 26 | _usdp already transferred to swapper_ 27 | 28 | ### _swapAssetToUsdp 29 | 30 | ```solidity 31 | function _swapAssetToUsdp(address _user, address _asset, uint256 _assetAmount, uint256 _minUsdpAmount) internal virtual returns (uint256 swappedUsdpAmount) 32 | ``` 33 | 34 | _asset already transferred to swapper_ 35 | 36 | ### swapUsdpToAsset 37 | 38 | ```solidity 39 | function swapUsdpToAsset(address _user, address _asset, uint256 _usdpAmount, uint256 _minAssetAmount) external returns (uint256 swappedAssetAmount) 40 | ``` 41 | 42 | usdp must be approved to swapper 43 | 44 | _asset must be sent to user after swap_ 45 | 46 | ### swapAssetToUsdp 47 | 48 | ```solidity 49 | function swapAssetToUsdp(address _user, address _asset, uint256 _assetAmount, uint256 _minUsdpAmount) external returns (uint256 swappedUsdpAmount) 50 | ``` 51 | 52 | asset must be approved to swapper 53 | 54 | _usdp must be sent to user after swap_ 55 | 56 | ### swapUsdpToAssetWithDirectSending 57 | 58 | ```solidity 59 | function swapUsdpToAssetWithDirectSending(address _user, address _asset, uint256 _usdpAmount, uint256 _minAssetAmount) public returns (uint256 swappedAssetAmount) 60 | ``` 61 | 62 | DO NOT SEND tokens to contract manually. For usage in contracts only. 63 | 64 | _for gas saving with usage in contracts tokens must be send directly to contract instead 65 | asset must be sent to user after swap_ 66 | 67 | ### swapAssetToUsdpWithDirectSending 68 | 69 | ```solidity 70 | function swapAssetToUsdpWithDirectSending(address _user, address _asset, uint256 _assetAmount, uint256 _minUsdpAmount) public returns (uint256 swappedUsdpAmount) 71 | ``` 72 | 73 | DO NOT SEND tokens to contract manually. For usage in contracts only. 74 | 75 | _for gas saving with usage in contracts tokens must be send directly to contract instead 76 | usdp must be sent to user after swap_ 77 | 78 | -------------------------------------------------------------------------------- /doc/dev-full/AssetParameters.md: -------------------------------------------------------------------------------- 1 | # Solidity API 2 | 3 | ## AssetParameters 4 | 5 | ### PARAM_FORCE_TRANSFER_ASSET_TO_OWNER_ON_LIQUIDATION 6 | 7 | ```solidity 8 | uint8 PARAM_FORCE_TRANSFER_ASSET_TO_OWNER_ON_LIQUIDATION 9 | ``` 10 | 11 | Some assets require a transfer of at least 1 unit of token 12 | to update internal logic related to staking rewards in case of full liquidation 13 | 14 | ### PARAM_FORCE_MOVE_WRAPPED_ASSET_POSITION_ON_LIQUIDATION 15 | 16 | ```solidity 17 | uint8 PARAM_FORCE_MOVE_WRAPPED_ASSET_POSITION_ON_LIQUIDATION 18 | ``` 19 | 20 | Some wrapped assets that require a manual position transfer between users 21 | since `transfer` doesn't do this 22 | 23 | ### needForceTransferAssetToOwnerOnLiquidation 24 | 25 | ```solidity 26 | function needForceTransferAssetToOwnerOnLiquidation(uint256 assetBoolParams) internal pure returns (bool) 27 | ``` 28 | 29 | ### needForceMoveWrappedAssetPositionOnLiquidation 30 | 31 | ```solidity 32 | function needForceMoveWrappedAssetPositionOnLiquidation(uint256 assetBoolParams) internal pure returns (bool) 33 | ``` 34 | 35 | -------------------------------------------------------------------------------- /doc/dev-full/AssetParametersViewer.md: -------------------------------------------------------------------------------- 1 | # Solidity API 2 | 3 | ## AssetParametersViewer 4 | 5 | Views collaterals in one request to save node requests and speed up dapps. 6 | 7 | _It makes no sense to clog a node with hundreds of RPC requests and slow a client app/dapp. Since usually 8 | a huge amount of gas is available to node static calls, we can aggregate asset data in a huge batch on the 9 | node's side and pull it to the client._ 10 | 11 | ### vaultParameters 12 | 13 | ```solidity 14 | contract IVaultParameters vaultParameters 15 | ``` 16 | 17 | ### vaultManagerParameters 18 | 19 | ```solidity 20 | contract IVaultManagerParameters vaultManagerParameters 21 | ``` 22 | 23 | ### vaultManagerBorrowFeeParameters 24 | 25 | ```solidity 26 | contract IVaultManagerBorrowFeeParameters vaultManagerBorrowFeeParameters 27 | ``` 28 | 29 | ### assetsBooleanParameters 30 | 31 | ```solidity 32 | contract IAssetsBooleanParameters assetsBooleanParameters 33 | ``` 34 | 35 | ### AssetParametersStruct 36 | 37 | ```solidity 38 | struct AssetParametersStruct { 39 | address asset; 40 | uint256 stabilityFee; 41 | uint256 liquidationFee; 42 | uint256 initialCollateralRatio; 43 | uint256 liquidationRatio; 44 | uint256 liquidationDiscount; 45 | uint256 devaluationPeriod; 46 | uint256 tokenDebtLimit; 47 | uint256[] oracles; 48 | uint256 minColPercent; 49 | uint256 maxColPercent; 50 | uint256 borrowFee; 51 | bool forceTransferAssetToOwnerOnLiquidation; 52 | bool forceMoveWrappedAssetPositionOnLiquidation; 53 | } 54 | ``` 55 | 56 | ### constructor 57 | 58 | ```solidity 59 | constructor(address _vaultManagerParameters, address _vaultManagerBorrowFeeParameters, address _assetsBooleanParameters) public 60 | ``` 61 | 62 | ### getAssetParameters 63 | 64 | ```solidity 65 | function getAssetParameters(address asset, uint256 maxOracleTypesToSearch) public view returns (struct AssetParametersViewer.AssetParametersStruct r) 66 | ``` 67 | 68 | Get parameters of one asset 69 | 70 | #### Parameters 71 | 72 | | Name | Type | Description | 73 | | ---- | ---- | ----------- | 74 | | asset | address | asset address | 75 | | maxOracleTypesToSearch | uint256 | since complete list of oracle types is unknown, we'll check types up to this number | 76 | 77 | ### getMultiAssetParameters 78 | 79 | ```solidity 80 | function getMultiAssetParameters(address[] assets, uint256 maxOracleTypesToSearch) external view returns (struct AssetParametersViewer.AssetParametersStruct[] r) 81 | ``` 82 | 83 | Get parameters of many assets 84 | 85 | #### Parameters 86 | 87 | | Name | Type | Description | 88 | | ---- | ---- | ----------- | 89 | | assets | address[] | asset addresses | 90 | | maxOracleTypesToSearch | uint256 | since complete list of oracle types is unknown, we'll check types up to this number | 91 | 92 | -------------------------------------------------------------------------------- /doc/dev-full/AssetsBooleanParameters.md: -------------------------------------------------------------------------------- 1 | # Solidity API 2 | 3 | ## AssetsBooleanParameters 4 | 5 | ### values 6 | 7 | ```solidity 8 | mapping(address => uint256) values 9 | ``` 10 | 11 | ### constructor 12 | 13 | ```solidity 14 | constructor(address _vaultParameters, address[] _initialAssets, uint8[] _initialParams) public 15 | ``` 16 | 17 | ### get 18 | 19 | ```solidity 20 | function get(address _asset, uint8 _param) external view returns (bool) 21 | ``` 22 | 23 | Get value of _param for _asset 24 | 25 | _see ParametersConstants_ 26 | 27 | ### getAll 28 | 29 | ```solidity 30 | function getAll(address _asset) external view returns (uint256) 31 | ``` 32 | 33 | Get values of all params for _asset. The 0th bit of returned uint id the value of param=0, etc 34 | 35 | ### set 36 | 37 | ```solidity 38 | function set(address _asset, uint8 _param, bool _value) public 39 | ``` 40 | 41 | Set value of _param for _asset 42 | 43 | _see ParametersConstants_ 44 | 45 | ### _set 46 | 47 | ```solidity 48 | function _set(address _asset, uint8 _param, bool _value) internal 49 | ``` 50 | 51 | -------------------------------------------------------------------------------- /doc/dev-full/Auth.md: -------------------------------------------------------------------------------- 1 | # Solidity API 2 | 3 | ## Auth 4 | 5 | _Manages USDP's system access_ 6 | 7 | ### vaultParameters 8 | 9 | ```solidity 10 | contract VaultParameters vaultParameters 11 | ``` 12 | 13 | ### constructor 14 | 15 | ```solidity 16 | constructor(address _parameters) public 17 | ``` 18 | 19 | ### onlyManager 20 | 21 | ```solidity 22 | modifier onlyManager() 23 | ``` 24 | 25 | ### hasVaultAccess 26 | 27 | ```solidity 28 | modifier hasVaultAccess() 29 | ``` 30 | 31 | ### onlyVault 32 | 33 | ```solidity 34 | modifier onlyVault() 35 | ``` 36 | 37 | -------------------------------------------------------------------------------- /doc/dev-full/Auth2.md: -------------------------------------------------------------------------------- 1 | # Solidity API 2 | 3 | ## Auth2 4 | 5 | _Manages USDP's system access 6 | copy of Auth from VaultParameters.sol but with immutable vaultParameters for saving gas_ 7 | 8 | ### vaultParameters 9 | 10 | ```solidity 11 | contract VaultParameters vaultParameters 12 | ``` 13 | 14 | ### constructor 15 | 16 | ```solidity 17 | constructor(address _parameters) public 18 | ``` 19 | 20 | ### onlyManager 21 | 22 | ```solidity 23 | modifier onlyManager() 24 | ``` 25 | 26 | ### hasVaultAccess 27 | 28 | ```solidity 29 | modifier hasVaultAccess() 30 | ``` 31 | 32 | ### onlyVault 33 | 34 | ```solidity 35 | modifier onlyVault() 36 | ``` 37 | 38 | -------------------------------------------------------------------------------- /doc/dev-full/BearingAssetOracle.md: -------------------------------------------------------------------------------- 1 | # Solidity API 2 | 3 | ## BearingAssetOracle 4 | 5 | _Wrapper to quote bearing assets like xSUSHI_ 6 | 7 | ### oracleRegistry 8 | 9 | ```solidity 10 | contract IOracleRegistry oracleRegistry 11 | ``` 12 | 13 | ### underlyings 14 | 15 | ```solidity 16 | mapping(address => address) underlyings 17 | ``` 18 | 19 | ### NewUnderlying 20 | 21 | ```solidity 22 | event NewUnderlying(address bearing, address underlying) 23 | ``` 24 | 25 | ### constructor 26 | 27 | ```solidity 28 | constructor(address _vaultParameters, address _oracleRegistry) public 29 | ``` 30 | 31 | ### setUnderlying 32 | 33 | ```solidity 34 | function setUnderlying(address bearing, address underlying) external 35 | ``` 36 | 37 | ### assetToUsd 38 | 39 | ```solidity 40 | function assetToUsd(address bearing, uint256 amount) public view returns (uint256) 41 | ``` 42 | 43 | ### bearingToUnderlying 44 | 45 | ```solidity 46 | function bearingToUnderlying(address bearing, uint256 amount) public view returns (address, uint256) 47 | ``` 48 | 49 | -------------------------------------------------------------------------------- /doc/dev-full/BridgedUsdpOracle.md: -------------------------------------------------------------------------------- 1 | # Solidity API 2 | 3 | ## BridgedUsdpOracle 4 | 5 | _Oracle to quote bridged from other chains USDP_ 6 | 7 | ### Q112 8 | 9 | ```solidity 10 | uint256 Q112 11 | ``` 12 | 13 | ### bridgedUsdp 14 | 15 | ```solidity 16 | mapping(address => bool) bridgedUsdp 17 | ``` 18 | 19 | ### Added 20 | 21 | ```solidity 22 | event Added(address _usdp) 23 | ``` 24 | 25 | ### Removed 26 | 27 | ```solidity 28 | event Removed(address _usdp) 29 | ``` 30 | 31 | ### constructor 32 | 33 | ```solidity 34 | constructor(address vaultParameters, address[] _bridgedUsdp) public 35 | ``` 36 | 37 | ### add 38 | 39 | ```solidity 40 | function add(address _usdp) external 41 | ``` 42 | 43 | ### remove 44 | 45 | ```solidity 46 | function remove(address _usdp) external 47 | ``` 48 | 49 | ### assetToUsd 50 | 51 | ```solidity 52 | function assetToUsd(address asset, uint256 amount) public view returns (uint256) 53 | ``` 54 | 55 | -------------------------------------------------------------------------------- /doc/dev-full/CDPRegistry.md: -------------------------------------------------------------------------------- 1 | # Solidity API 2 | 3 | ## CDPRegistry 4 | 5 | ### CDP 6 | 7 | ```solidity 8 | struct CDP { 9 | address asset; 10 | address owner; 11 | } 12 | ``` 13 | 14 | ### cdpList 15 | 16 | ```solidity 17 | mapping(address => address[]) cdpList 18 | ``` 19 | 20 | ### cdpIndex 21 | 22 | ```solidity 23 | mapping(address => mapping(address => uint256)) cdpIndex 24 | ``` 25 | 26 | ### vault 27 | 28 | ```solidity 29 | contract IVault vault 30 | ``` 31 | 32 | ### cr 33 | 34 | ```solidity 35 | contract ICollateralRegistry cr 36 | ``` 37 | 38 | ### Added 39 | 40 | ```solidity 41 | event Added(address asset, address owner) 42 | ``` 43 | 44 | ### Removed 45 | 46 | ```solidity 47 | event Removed(address asset, address owner) 48 | ``` 49 | 50 | ### constructor 51 | 52 | ```solidity 53 | constructor(address _vault, address _collateralRegistry) public 54 | ``` 55 | 56 | ### checkpoint 57 | 58 | ```solidity 59 | function checkpoint(address asset, address owner) public 60 | ``` 61 | 62 | ### batchCheckpointForAsset 63 | 64 | ```solidity 65 | function batchCheckpointForAsset(address asset, address[] owners) external 66 | ``` 67 | 68 | ### batchCheckpoint 69 | 70 | ```solidity 71 | function batchCheckpoint(address[] assets, address[] owners) external 72 | ``` 73 | 74 | ### isAlive 75 | 76 | ```solidity 77 | function isAlive(address asset, address owner) public view returns (bool) 78 | ``` 79 | 80 | ### isListed 81 | 82 | ```solidity 83 | function isListed(address asset, address owner) public view returns (bool) 84 | ``` 85 | 86 | ### _removeCdp 87 | 88 | ```solidity 89 | function _removeCdp(address asset, address owner) internal 90 | ``` 91 | 92 | ### _addCdp 93 | 94 | ```solidity 95 | function _addCdp(address asset, address owner) internal 96 | ``` 97 | 98 | ### getCdpsByCollateral 99 | 100 | ```solidity 101 | function getCdpsByCollateral(address asset) external view returns (struct CDPRegistry.CDP[] cdps) 102 | ``` 103 | 104 | ### getCdpsByOwner 105 | 106 | ```solidity 107 | function getCdpsByOwner(address owner) external view returns (struct CDPRegistry.CDP[] r) 108 | ``` 109 | 110 | ### getAllCdps 111 | 112 | ```solidity 113 | function getAllCdps() external view returns (struct CDPRegistry.CDP[] r) 114 | ``` 115 | 116 | ### getCdpsCount 117 | 118 | ```solidity 119 | function getCdpsCount() public view returns (uint256 totalCdpCount) 120 | ``` 121 | 122 | ### getCdpsCountForCollateral 123 | 124 | ```solidity 125 | function getCdpsCountForCollateral(address asset) public view returns (uint256) 126 | ``` 127 | 128 | -------------------------------------------------------------------------------- /doc/dev-full/ChainlinkedKeydonixOracleMainAssetAbstract.md: -------------------------------------------------------------------------------- 1 | # Solidity API 2 | 3 | ## ChainlinkedKeydonixOracleMainAssetAbstract 4 | 5 | ### WETH 6 | 7 | ```solidity 8 | address WETH 9 | ``` 10 | 11 | ### assetToEth 12 | 13 | ```solidity 14 | function assetToEth(address asset, uint256 amount, struct KeydonixOracleAbstract.ProofDataStruct proofData) public view virtual returns (uint256) 15 | ``` 16 | 17 | ### ethToUsd 18 | 19 | ```solidity 20 | function ethToUsd(uint256 ethAmount) public view virtual returns (uint256) 21 | ``` 22 | 23 | -------------------------------------------------------------------------------- /doc/dev-full/ChainlinkedKeydonixOraclePoolTokenAbstract.md: -------------------------------------------------------------------------------- 1 | # Solidity API 2 | 3 | ## ChainlinkedKeydonixOraclePoolTokenAbstract 4 | 5 | ### uniswapOracleMainAsset 6 | 7 | ```solidity 8 | contract ChainlinkedKeydonixOracleMainAssetAbstract uniswapOracleMainAsset 9 | ``` 10 | 11 | -------------------------------------------------------------------------------- /doc/dev-full/ChainlinkedOracleMainAsset.md: -------------------------------------------------------------------------------- 1 | # Solidity API 2 | 3 | ## ChainlinkedOracleMainAsset 4 | 5 | _Calculates the USD price of desired tokens_ 6 | 7 | ### usdAggregators 8 | 9 | ```solidity 10 | mapping(address => address) usdAggregators 11 | ``` 12 | 13 | ### ethAggregators 14 | 15 | ```solidity 16 | mapping(address => address) ethAggregators 17 | ``` 18 | 19 | ### Q112 20 | 21 | ```solidity 22 | uint256 Q112 23 | ``` 24 | 25 | ### USD_TYPE 26 | 27 | ```solidity 28 | uint256 USD_TYPE 29 | ``` 30 | 31 | ### ETH_TYPE 32 | 33 | ```solidity 34 | uint256 ETH_TYPE 35 | ``` 36 | 37 | ### WETH 38 | 39 | ```solidity 40 | address WETH 41 | ``` 42 | 43 | ### NewAggregator 44 | 45 | ```solidity 46 | event NewAggregator(address asset, address aggregator, uint256 aggType) 47 | ``` 48 | 49 | ### constructor 50 | 51 | ```solidity 52 | constructor(address[] tokenAddresses1, address[] _usdAggregators, address[] tokenAddresses2, address[] _ethAggregators, address weth, address vaultParameters) public 53 | ``` 54 | 55 | ### setAggregators 56 | 57 | ```solidity 58 | function setAggregators(address[] tokenAddresses1, address[] _usdAggregators, address[] tokenAddresses2, address[] _ethAggregators) external 59 | ``` 60 | 61 | ### assetToUsd 62 | 63 | ```solidity 64 | function assetToUsd(address asset, uint256 amount) public view returns (uint256) 65 | ``` 66 | 67 | {asset}/USD or {asset}/ETH pair must be registered at Chainlink 68 | 69 | #### Parameters 70 | 71 | | Name | Type | Description | 72 | | ---- | ---- | ----------- | 73 | | asset | address | The token address | 74 | | amount | uint256 | Amount of tokens | 75 | 76 | #### Return Values 77 | 78 | | Name | Type | Description | 79 | | ---- | ---- | ----------- | 80 | | [0] | uint256 | Q112-encoded price of asset amount in USD | 81 | 82 | ### _assetToUsd 83 | 84 | ```solidity 85 | function _assetToUsd(address asset, uint256 amount) internal view returns (uint256) 86 | ``` 87 | 88 | ### assetToEth 89 | 90 | ```solidity 91 | function assetToEth(address asset, uint256 amount) public view returns (uint256) 92 | ``` 93 | 94 | {asset}/ETH pair must be registered at Chainlink 95 | 96 | #### Parameters 97 | 98 | | Name | Type | Description | 99 | | ---- | ---- | ----------- | 100 | | asset | address | The token address | 101 | | amount | uint256 | Amount of tokens | 102 | 103 | #### Return Values 104 | 105 | | Name | Type | Description | 106 | | ---- | ---- | ----------- | 107 | | [0] | uint256 | Q112-encoded price of asset amount in ETH | 108 | 109 | ### ethToUsd 110 | 111 | ```solidity 112 | function ethToUsd(uint256 ethAmount) public view returns (uint256) 113 | ``` 114 | 115 | ETH/USD price feed from Chainlink, see for more info: https://feeds.chain.link/eth-usd 116 | returns The price of given amount of Ether in USD (0 decimals) 117 | 118 | ### usdToEth 119 | 120 | ```solidity 121 | function usdToEth(uint256 _usdAmount) public view returns (uint256) 122 | ``` 123 | 124 | -------------------------------------------------------------------------------- /doc/dev-full/ChainlinkedOracleSimple.md: -------------------------------------------------------------------------------- 1 | # Solidity API 2 | 3 | ## ChainlinkedOracleSimple 4 | 5 | ### WETH 6 | 7 | ```solidity 8 | address WETH 9 | ``` 10 | 11 | ### ethToUsd 12 | 13 | ```solidity 14 | function ethToUsd(uint256 ethAmount) public view virtual returns (uint256) 15 | ``` 16 | 17 | ### assetToEth 18 | 19 | ```solidity 20 | function assetToEth(address asset, uint256 amount) public view virtual returns (uint256) 21 | ``` 22 | 23 | -------------------------------------------------------------------------------- /doc/dev-full/CollateralRegistry.md: -------------------------------------------------------------------------------- 1 | # Solidity API 2 | 3 | ## CollateralRegistry 4 | 5 | ### CollateralAdded 6 | 7 | ```solidity 8 | event CollateralAdded(address asset) 9 | ``` 10 | 11 | ### CollateralRemoved 12 | 13 | ```solidity 14 | event CollateralRemoved(address asset) 15 | ``` 16 | 17 | ### collateralId 18 | 19 | ```solidity 20 | mapping(address => uint256) collateralId 21 | ``` 22 | 23 | ### collateralList 24 | 25 | ```solidity 26 | address[] collateralList 27 | ``` 28 | 29 | ### constructor 30 | 31 | ```solidity 32 | constructor(address _vaultParameters, address[] assets) public 33 | ``` 34 | 35 | ### addCollateral 36 | 37 | ```solidity 38 | function addCollateral(address asset) public 39 | ``` 40 | 41 | ### removeCollateral 42 | 43 | ```solidity 44 | function removeCollateral(address asset) public 45 | ``` 46 | 47 | ### isCollateral 48 | 49 | ```solidity 50 | function isCollateral(address asset) public view returns (bool) 51 | ``` 52 | 53 | ### collaterals 54 | 55 | ```solidity 56 | function collaterals() external view returns (address[]) 57 | ``` 58 | 59 | ### collateralsCount 60 | 61 | ```solidity 62 | function collateralsCount() external view returns (uint256) 63 | ``` 64 | 65 | -------------------------------------------------------------------------------- /doc/dev-full/CurveHelper.md: -------------------------------------------------------------------------------- 1 | # Solidity API 2 | 3 | ## CurveHelper 4 | 5 | ### MAX_COINS 6 | 7 | ```solidity 8 | int128 MAX_COINS 9 | ``` 10 | 11 | ### getCoinIndexInMetaPool 12 | 13 | ```solidity 14 | function getCoinIndexInMetaPool(contract ICurvePoolMeta _pool, address _coin) internal view returns (int128) 15 | ``` 16 | 17 | ### getCoinIndexInPool 18 | 19 | ```solidity 20 | function getCoinIndexInPool(contract ICurvePool _pool, address _coin) internal view returns (int128) 21 | ``` 22 | 23 | -------------------------------------------------------------------------------- /doc/dev-full/CurveLPOracle.md: -------------------------------------------------------------------------------- 1 | # Solidity API 2 | 3 | ## CurveLPOracle 4 | 5 | _Oracle to quote curve LP tokens_ 6 | 7 | ### Q112 8 | 9 | ```solidity 10 | uint256 Q112 11 | ``` 12 | 13 | ### PRECISION 14 | 15 | ```solidity 16 | uint256 PRECISION 17 | ``` 18 | 19 | ### curveProvider 20 | 21 | ```solidity 22 | contract ICurveProvider curveProvider 23 | ``` 24 | 25 | ### oracleRegistry 26 | 27 | ```solidity 28 | contract IOracleRegistry oracleRegistry 29 | ``` 30 | 31 | ### constructor 32 | 33 | ```solidity 34 | constructor(address _curveProvider, address _oracleRegistry) public 35 | ``` 36 | 37 | #### Parameters 38 | 39 | | Name | Type | Description | 40 | | ---- | ---- | ----------- | 41 | | _curveProvider | address | The address of the Curve Provider. Mainnet: 0x0000000022D53366457F9d5E68Ec105046FC4383 | 42 | | _oracleRegistry | address | The address of the OracleRegistry contract | 43 | 44 | ### assetToUsd 45 | 46 | ```solidity 47 | function assetToUsd(address asset, uint256 amount) public view returns (uint256) 48 | ``` 49 | 50 | -------------------------------------------------------------------------------- /doc/dev-full/CyTokenOracle.md: -------------------------------------------------------------------------------- 1 | # Solidity API 2 | 3 | ## CyTokenOracle 4 | 5 | _Wrapper to quote cyToken assets like cyWETH, cyDAI, cyUSDT, cyUSDC 6 | cyToken list: https://docs.cream.finance/iron-bank/iron-bank#yearn-token-cytoken_ 7 | 8 | ### expScale 9 | 10 | ```solidity 11 | uint256 expScale 12 | ``` 13 | 14 | ### enabledImplementations 15 | 16 | ```solidity 17 | mapping(address => bool) enabledImplementations 18 | ``` 19 | 20 | ### oracleRegistry 21 | 22 | ```solidity 23 | contract IOracleRegistry oracleRegistry 24 | ``` 25 | 26 | ### ImplementationChanged 27 | 28 | ```solidity 29 | event ImplementationChanged(address implementation, bool enabled) 30 | ``` 31 | 32 | ### constructor 33 | 34 | ```solidity 35 | constructor(address _vaultParameters, address _oracleRegistry, address[] impls) public 36 | ``` 37 | 38 | ### setImplementation 39 | 40 | ```solidity 41 | function setImplementation(address impl, bool enable) external 42 | ``` 43 | 44 | ### assetToUsd 45 | 46 | ```solidity 47 | function assetToUsd(address bearing, uint256 amount) public view returns (uint256) 48 | ``` 49 | 50 | ### bearingToUnderlying 51 | 52 | ```solidity 53 | function bearingToUnderlying(address bearing, uint256 amount) public view returns (address, uint256) 54 | ``` 55 | 56 | -------------------------------------------------------------------------------- /doc/dev-full/ERC20Like.md: -------------------------------------------------------------------------------- 1 | # Solidity API 2 | 3 | ## ERC20Like 4 | 5 | ### balanceOf 6 | 7 | ```solidity 8 | function balanceOf(address) external view returns (uint256) 9 | ``` 10 | 11 | ### decimals 12 | 13 | ```solidity 14 | function decimals() external view returns (uint8) 15 | ``` 16 | 17 | ### transfer 18 | 19 | ```solidity 20 | function transfer(address, uint256) external returns (bool) 21 | ``` 22 | 23 | ### transferFrom 24 | 25 | ```solidity 26 | function transferFrom(address, address, uint256) external returns (bool) 27 | ``` 28 | 29 | ### totalSupply 30 | 31 | ```solidity 32 | function totalSupply() external view returns (uint256) 33 | ``` 34 | 35 | -------------------------------------------------------------------------------- /doc/dev-full/IUniswapV2Factory.md: -------------------------------------------------------------------------------- 1 | # Solidity API 2 | 3 | ## IUniswapV2Factory 4 | 5 | ### PairCreated 6 | 7 | ```solidity 8 | event PairCreated(address token0, address token1, address pair, uint256) 9 | ``` 10 | 11 | ### getPair 12 | 13 | ```solidity 14 | function getPair(address tokenA, address tokenB) external view returns (address pair) 15 | ``` 16 | 17 | ### allPairs 18 | 19 | ```solidity 20 | function allPairs(uint256) external view returns (address pair) 21 | ``` 22 | 23 | ### allPairsLength 24 | 25 | ```solidity 26 | function allPairsLength() external view returns (uint256) 27 | ``` 28 | 29 | ### feeTo 30 | 31 | ```solidity 32 | function feeTo() external view returns (address) 33 | ``` 34 | 35 | ### feeToSetter 36 | 37 | ```solidity 38 | function feeToSetter() external view returns (address) 39 | ``` 40 | 41 | ### createPair 42 | 43 | ```solidity 44 | function createPair(address tokenA, address tokenB) external returns (address pair) 45 | ``` 46 | 47 | -------------------------------------------------------------------------------- /doc/dev-full/KeydonixOracleAbstract.md: -------------------------------------------------------------------------------- 1 | # Solidity API 2 | 3 | ## KeydonixOracleAbstract 4 | 5 | ### Q112 6 | 7 | ```solidity 8 | uint256 Q112 9 | ``` 10 | 11 | ### ProofDataStruct 12 | 13 | ```solidity 14 | struct ProofDataStruct { 15 | bytes block; 16 | bytes accountProofNodesRlp; 17 | bytes reserveAndTimestampProofNodesRlp; 18 | bytes priceAccumulatorProofNodesRlp; 19 | } 20 | ``` 21 | 22 | ### assetToUsd 23 | 24 | ```solidity 25 | function assetToUsd(address asset, uint256 amount, struct KeydonixOracleAbstract.ProofDataStruct proofData) public view virtual returns (uint256) 26 | ``` 27 | 28 | -------------------------------------------------------------------------------- /doc/dev-full/LiquidationAuction02.md: -------------------------------------------------------------------------------- 1 | # Solidity API 2 | 3 | ## LiquidationAuction02 4 | 5 | ### vault 6 | 7 | ```solidity 8 | contract IVault vault 9 | ``` 10 | 11 | ### vaultManagerParameters 12 | 13 | ```solidity 14 | contract IVaultManagerParameters vaultManagerParameters 15 | ``` 16 | 17 | ### cdpRegistry 18 | 19 | ```solidity 20 | contract ICDPRegistry cdpRegistry 21 | ``` 22 | 23 | ### assetsBooleanParameters 24 | 25 | ```solidity 26 | contract IAssetsBooleanParameters assetsBooleanParameters 27 | ``` 28 | 29 | ### DENOMINATOR_1E2 30 | 31 | ```solidity 32 | uint256 DENOMINATOR_1E2 33 | ``` 34 | 35 | ### WRAPPED_TO_UNDERLYING_ORACLE_TYPE 36 | 37 | ```solidity 38 | uint256 WRAPPED_TO_UNDERLYING_ORACLE_TYPE 39 | ``` 40 | 41 | ### Buyout 42 | 43 | ```solidity 44 | event Buyout(address asset, address owner, address buyer, uint256 amount, uint256 price, uint256 penalty) 45 | ``` 46 | 47 | _Trigger when buyouts are happened_ 48 | 49 | ### checkpoint 50 | 51 | ```solidity 52 | modifier checkpoint(address asset, address owner) 53 | ``` 54 | 55 | ### constructor 56 | 57 | ```solidity 58 | constructor(address _vaultManagerParameters, address _cdpRegistry, address _assetsBooleanParameters) public 59 | ``` 60 | 61 | #### Parameters 62 | 63 | | Name | Type | Description | 64 | | ---- | ---- | ----------- | 65 | | _vaultManagerParameters | address | The address of the contract with Vault manager parameters | 66 | | _cdpRegistry | address | The address of the CDP registry | 67 | | _assetsBooleanParameters | address | The address of the AssetsBooleanParameters | 68 | 69 | ### buyout 70 | 71 | ```solidity 72 | function buyout(address asset, address owner) public 73 | ``` 74 | 75 | _Buyouts a position's collateral_ 76 | 77 | #### Parameters 78 | 79 | | Name | Type | Description | 80 | | ---- | ---- | ----------- | 81 | | asset | address | The address of the main collateral token of a position | 82 | | owner | address | The owner of a position | 83 | 84 | ### _calcLiquidationParams 85 | 86 | ```solidity 87 | function _calcLiquidationParams(uint256 depreciationPeriod, uint256 blocksPast, uint256 startingPrice, uint256 debtWithPenalty, uint256 collateralInPosition) internal pure returns (uint256 collateralToBuyer, uint256 collateralToOwner, uint256 price) 88 | ``` 89 | 90 | -------------------------------------------------------------------------------- /doc/dev-full/Math.md: -------------------------------------------------------------------------------- 1 | # Solidity API 2 | 3 | ## Math 4 | 5 | _Standard math utilities missing in the Solidity language._ 6 | 7 | ### max 8 | 9 | ```solidity 10 | function max(uint256 a, uint256 b) internal pure returns (uint256) 11 | ``` 12 | 13 | _Returns the largest of two numbers._ 14 | 15 | ### min 16 | 17 | ```solidity 18 | function min(uint256 a, uint256 b) internal pure returns (uint256) 19 | ``` 20 | 21 | _Returns the smallest of two numbers._ 22 | 23 | ### average 24 | 25 | ```solidity 26 | function average(uint256 a, uint256 b) internal pure returns (uint256) 27 | ``` 28 | 29 | _Returns the average of two numbers. The result is rounded towards 30 | zero._ 31 | 32 | ### sqrt 33 | 34 | ```solidity 35 | function sqrt(uint256 x) internal pure returns (uint256 y) 36 | ``` 37 | 38 | _babylonian method (https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method)_ 39 | 40 | -------------------------------------------------------------------------------- /doc/dev-full/Migrations.md: -------------------------------------------------------------------------------- 1 | # Solidity API 2 | 3 | ## Migrations 4 | 5 | ### owner 6 | 7 | ```solidity 8 | address owner 9 | ``` 10 | 11 | ### last_completed_migration 12 | 13 | ```solidity 14 | uint256 last_completed_migration 15 | ``` 16 | 17 | ### constructor 18 | 19 | ```solidity 20 | constructor() public 21 | ``` 22 | 23 | ### restricted 24 | 25 | ```solidity 26 | modifier restricted() 27 | ``` 28 | 29 | ### setCompleted 30 | 31 | ```solidity 32 | function setCompleted(uint256 completed) public 33 | ``` 34 | 35 | -------------------------------------------------------------------------------- /doc/dev-full/OraclePoolToken.md: -------------------------------------------------------------------------------- 1 | # Solidity API 2 | 3 | ## OraclePoolToken 4 | 5 | _Calculates the USD price of Uniswap LP tokens_ 6 | 7 | ### oracleRegistry 8 | 9 | ```solidity 10 | contract IOracleRegistry oracleRegistry 11 | ``` 12 | 13 | ### WETH 14 | 15 | ```solidity 16 | address WETH 17 | ``` 18 | 19 | ### Q112 20 | 21 | ```solidity 22 | uint256 Q112 23 | ``` 24 | 25 | ### constructor 26 | 27 | ```solidity 28 | constructor(address _oracleRegistry) public 29 | ``` 30 | 31 | ### assetToUsd 32 | 33 | ```solidity 34 | function assetToUsd(address asset, uint256 amount) public view returns (uint256) 35 | ``` 36 | 37 | Flashloan-resistant logic to determine USD price of Uniswap LP tokens 38 | Pair must be registered at Chainlink 39 | 40 | #### Parameters 41 | 42 | | Name | Type | Description | 43 | | ---- | ---- | ----------- | 44 | | asset | address | The LP token address | 45 | | amount | uint256 | Amount of asset | 46 | 47 | #### Return Values 48 | 49 | | Name | Type | Description | 50 | | ---- | ---- | ----------- | 51 | | [0] | uint256 | Q112 encoded price of asset in USD | 52 | 53 | ### sqrt 54 | 55 | ```solidity 56 | function sqrt(uint256 x) internal pure returns (uint256 y) 57 | ``` 58 | 59 | -------------------------------------------------------------------------------- /doc/dev-full/OracleRegistry.md: -------------------------------------------------------------------------------- 1 | # Solidity API 2 | 3 | ## OracleRegistry 4 | 5 | ### Oracle 6 | 7 | ```solidity 8 | struct Oracle { 9 | uint256 oracleType; 10 | address oracleAddress; 11 | } 12 | ``` 13 | 14 | ### maxOracleType 15 | 16 | ```solidity 17 | uint256 maxOracleType 18 | ``` 19 | 20 | ### WETH 21 | 22 | ```solidity 23 | address WETH 24 | ``` 25 | 26 | ### oracleTypeByAsset 27 | 28 | ```solidity 29 | mapping(address => uint256) oracleTypeByAsset 30 | ``` 31 | 32 | ### oracleByType 33 | 34 | ```solidity 35 | mapping(uint256 => address) oracleByType 36 | ``` 37 | 38 | ### oracleTypeByOracle 39 | 40 | ```solidity 41 | mapping(address => uint256) oracleTypeByOracle 42 | ``` 43 | 44 | ### keydonixOracleTypes 45 | 46 | ```solidity 47 | uint256[] keydonixOracleTypes 48 | ``` 49 | 50 | ### AssetOracle 51 | 52 | ```solidity 53 | event AssetOracle(address asset, uint256 oracleType) 54 | ``` 55 | 56 | ### OracleType 57 | 58 | ```solidity 59 | event OracleType(uint256 oracleType, address oracle) 60 | ``` 61 | 62 | ### KeydonixOracleTypes 63 | 64 | ```solidity 65 | event KeydonixOracleTypes() 66 | ``` 67 | 68 | ### validAddress 69 | 70 | ```solidity 71 | modifier validAddress(address asset) 72 | ``` 73 | 74 | ### validType 75 | 76 | ```solidity 77 | modifier validType(uint256 _type) 78 | ``` 79 | 80 | ### constructor 81 | 82 | ```solidity 83 | constructor(address vaultParameters, address _weth) public 84 | ``` 85 | 86 | ### setKeydonixOracleTypes 87 | 88 | ```solidity 89 | function setKeydonixOracleTypes(uint256[] _keydonixOracleTypes) public 90 | ``` 91 | 92 | ### setOracle 93 | 94 | ```solidity 95 | function setOracle(uint256 oracleType, address oracle) public 96 | ``` 97 | 98 | ### unsetOracle 99 | 100 | ```solidity 101 | function unsetOracle(uint256 oracleType) public 102 | ``` 103 | 104 | ### setOracleTypeForAsset 105 | 106 | ```solidity 107 | function setOracleTypeForAsset(address asset, uint256 oracleType) public 108 | ``` 109 | 110 | ### setOracleTypeForAssets 111 | 112 | ```solidity 113 | function setOracleTypeForAssets(address[] assets, uint256 oracleType) public 114 | ``` 115 | 116 | ### unsetOracleForAsset 117 | 118 | ```solidity 119 | function unsetOracleForAsset(address asset) public 120 | ``` 121 | 122 | ### unsetOracleForAssets 123 | 124 | ```solidity 125 | function unsetOracleForAssets(address[] assets) public 126 | ``` 127 | 128 | ### getOracles 129 | 130 | ```solidity 131 | function getOracles() external view returns (struct OracleRegistry.Oracle[] foundOracles) 132 | ``` 133 | 134 | ### getKeydonixOracleTypes 135 | 136 | ```solidity 137 | function getKeydonixOracleTypes() external view returns (uint256[]) 138 | ``` 139 | 140 | ### oracleByAsset 141 | 142 | ```solidity 143 | function oracleByAsset(address asset) external view returns (address) 144 | ``` 145 | 146 | -------------------------------------------------------------------------------- /doc/dev-full/OracleSimple.md: -------------------------------------------------------------------------------- 1 | # Solidity API 2 | 3 | ## OracleSimple 4 | 5 | ### assetToUsd 6 | 7 | ```solidity 8 | function assetToUsd(address asset, uint256 amount) public view virtual returns (uint256) 9 | ``` 10 | 11 | -------------------------------------------------------------------------------- /doc/dev-full/OracleSimplePoolToken.md: -------------------------------------------------------------------------------- 1 | # Solidity API 2 | 3 | ## OracleSimplePoolToken 4 | 5 | ### oracleMainAsset 6 | 7 | ```solidity 8 | contract ChainlinkedOracleSimple oracleMainAsset 9 | ``` 10 | 11 | -------------------------------------------------------------------------------- /doc/dev-full/ReentrancyGuard.md: -------------------------------------------------------------------------------- 1 | # Solidity API 2 | 3 | ## ReentrancyGuard 4 | 5 | _Contract module that helps prevent reentrant calls to a function. 6 | 7 | Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier 8 | available, which can be applied to functions to make sure there are no nested 9 | (reentrant) calls to them. 10 | 11 | Note that because there is a single `nonReentrant` guard, functions marked as 12 | `nonReentrant` may not call one another. This can be worked around by making 13 | those functions `private`, and then adding `external` `nonReentrant` entry 14 | points to them. 15 | 16 | TIP: If you would like to learn more about reentrancy and alternative ways 17 | to protect against it, check out our blog post 18 | https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]._ 19 | 20 | ### constructor 21 | 22 | ```solidity 23 | constructor() public 24 | ``` 25 | 26 | ### nonReentrant 27 | 28 | ```solidity 29 | modifier nonReentrant() 30 | ``` 31 | 32 | _Prevents a contract from calling itself, directly or indirectly. 33 | Calling a `nonReentrant` function from another `nonReentrant` 34 | function is not supported. It is possible to prevent this from happening 35 | by making the `nonReentrant` function external, and make it call a 36 | `private` function that does the actual work._ 37 | 38 | -------------------------------------------------------------------------------- /doc/dev-full/SafeMath.md: -------------------------------------------------------------------------------- 1 | # Solidity API 2 | 3 | ## SafeMath 4 | 5 | _Math operations with safety checks that throw on error_ 6 | 7 | ### mul 8 | 9 | ```solidity 10 | function mul(uint256 a, uint256 b) internal pure returns (uint256 c) 11 | ``` 12 | 13 | _Multiplies two numbers, throws on overflow._ 14 | 15 | ### div 16 | 17 | ```solidity 18 | function div(uint256 a, uint256 b) internal pure returns (uint256) 19 | ``` 20 | 21 | _Integer division of two numbers, truncating the quotient._ 22 | 23 | ### sub 24 | 25 | ```solidity 26 | function sub(uint256 a, uint256 b) internal pure returns (uint256) 27 | ``` 28 | 29 | _Subtracts two numbers, throws on overflow (i.e. if subtrahend is greater than minuend)._ 30 | 31 | ### add 32 | 33 | ```solidity 34 | function add(uint256 a, uint256 b) internal pure returns (uint256 c) 35 | ``` 36 | 37 | _Adds two numbers, throws on overflow._ 38 | 39 | -------------------------------------------------------------------------------- /doc/dev-full/SwapperUniswapV2Lp.md: -------------------------------------------------------------------------------- 1 | # Solidity API 2 | 3 | ## SwapperUniswapV2Lp 4 | 5 | _swap usdp/any uniswapv2 lp_ 6 | 7 | ### WETH 8 | 9 | ```solidity 10 | address WETH 11 | ``` 12 | 13 | ### wethSwapper 14 | 15 | ```solidity 16 | contract ISwapper wethSwapper 17 | ``` 18 | 19 | ### constructor 20 | 21 | ```solidity 22 | constructor(address _vaultParameters, address _weth, address _usdp, address _wethSwapper) public 23 | ``` 24 | 25 | ### predictAssetOut 26 | 27 | ```solidity 28 | function predictAssetOut(address _asset, uint256 _usdpAmountIn) external view returns (uint256 predictedAssetAmount) 29 | ``` 30 | 31 | Predict asset amount after usdp swap 32 | 33 | ### predictUsdpOut 34 | 35 | ```solidity 36 | function predictUsdpOut(address _asset, uint256 _assetAmountIn) external view returns (uint256 predictedUsdpAmount) 37 | ``` 38 | 39 | Predict USDP amount after asset swap 40 | 41 | ### _swapUsdpToAsset 42 | 43 | ```solidity 44 | function _swapUsdpToAsset(address _user, address _asset, uint256 _usdpAmount, uint256) internal returns (uint256 swappedAssetAmount) 45 | ``` 46 | 47 | ### _swapAssetToUsdp 48 | 49 | ```solidity 50 | function _swapAssetToUsdp(address _user, address _asset, uint256 _assetAmount, uint256) internal returns (uint256 swappedUsdpAmount) 51 | ``` 52 | 53 | ### _swapPairTokens 54 | 55 | ```solidity 56 | function _swapPairTokens(contract IUniswapV2PairFull _pair, address _token, uint256 _tokenId, uint256 _amount, address _to) internal returns (uint256 tokenAmount) 57 | ``` 58 | 59 | -------------------------------------------------------------------------------- /doc/dev-full/SwapperWethViaCurve.md: -------------------------------------------------------------------------------- 1 | # Solidity API 2 | 3 | ## SwapperWethViaCurve 4 | 5 | _swap usdp/weth_ 6 | 7 | ### WETH 8 | 9 | ```solidity 10 | contract IERC20 WETH 11 | ``` 12 | 13 | ### USDT 14 | 15 | ```solidity 16 | contract IERC20 USDT 17 | ``` 18 | 19 | ### USDP_3CRV_POOL 20 | 21 | ```solidity 22 | contract ICurvePoolMeta USDP_3CRV_POOL 23 | ``` 24 | 25 | ### USDP_3CRV_POOL_USDP 26 | 27 | ```solidity 28 | int128 USDP_3CRV_POOL_USDP 29 | ``` 30 | 31 | ### USDP_3CRV_POOL_USDT 32 | 33 | ```solidity 34 | int128 USDP_3CRV_POOL_USDT 35 | ``` 36 | 37 | ### TRICRYPTO2_POOL 38 | 39 | ```solidity 40 | contract ICurvePoolCrypto TRICRYPTO2_POOL 41 | ``` 42 | 43 | ### TRICRYPTO2_USDT 44 | 45 | ```solidity 46 | uint256 TRICRYPTO2_USDT 47 | ``` 48 | 49 | ### TRICRYPTO2_WETH 50 | 51 | ```solidity 52 | uint256 TRICRYPTO2_WETH 53 | ``` 54 | 55 | ### constructor 56 | 57 | ```solidity 58 | constructor(address _vaultParameters, address _weth, address _usdp, address _usdt, address _usdp3crvPool, address _tricrypto2Pool) public 59 | ``` 60 | 61 | ### predictAssetOut 62 | 63 | ```solidity 64 | function predictAssetOut(address _asset, uint256 _usdpAmountIn) external view returns (uint256 predictedAssetAmount) 65 | ``` 66 | 67 | Predict asset amount after usdp swap 68 | 69 | ### predictUsdpOut 70 | 71 | ```solidity 72 | function predictUsdpOut(address _asset, uint256 _assetAmountIn) external view returns (uint256 predictedUsdpAmount) 73 | ``` 74 | 75 | _calculates with some small (~0.005%) error bcs of approximate calculations of fee in get_dy_underlying_ 76 | 77 | ### _swapUsdpToAsset 78 | 79 | ```solidity 80 | function _swapUsdpToAsset(address _user, address _asset, uint256 _usdpAmount, uint256) internal returns (uint256 swappedAssetAmount) 81 | ``` 82 | 83 | ### _swapAssetToUsdp 84 | 85 | ```solidity 86 | function _swapAssetToUsdp(address _user, address _asset, uint256 _assetAmount, uint256) internal returns (uint256 swappedUsdpAmount) 87 | ``` 88 | 89 | -------------------------------------------------------------------------------- /doc/dev-full/SwappersRegistry.md: -------------------------------------------------------------------------------- 1 | # Solidity API 2 | 3 | ## SwappersRegistry 4 | 5 | ### SwapperInfo 6 | 7 | ```solidity 8 | struct SwapperInfo { 9 | uint240 id; 10 | bool exists; 11 | } 12 | ``` 13 | 14 | ### swappersInfo 15 | 16 | ```solidity 17 | mapping(contract ISwapper => struct SwappersRegistry.SwapperInfo) swappersInfo 18 | ``` 19 | 20 | ### swappers 21 | 22 | ```solidity 23 | contract ISwapper[] swappers 24 | ``` 25 | 26 | ### constructor 27 | 28 | ```solidity 29 | constructor(address _vaultParameters) public 30 | ``` 31 | 32 | ### getSwappersLength 33 | 34 | ```solidity 35 | function getSwappersLength() external view returns (uint256) 36 | ``` 37 | 38 | ### getSwapperId 39 | 40 | ```solidity 41 | function getSwapperId(contract ISwapper _swapper) external view returns (uint256) 42 | ``` 43 | 44 | ### getSwapper 45 | 46 | ```solidity 47 | function getSwapper(uint256 _id) external view returns (contract ISwapper) 48 | ``` 49 | 50 | ### hasSwapper 51 | 52 | ```solidity 53 | function hasSwapper(contract ISwapper _swapper) public view returns (bool) 54 | ``` 55 | 56 | ### getSwappers 57 | 58 | ```solidity 59 | function getSwappers() external view returns (contract ISwapper[]) 60 | ``` 61 | 62 | ### add 63 | 64 | ```solidity 65 | function add(contract ISwapper _swapper) public 66 | ``` 67 | 68 | ### remove 69 | 70 | ```solidity 71 | function remove(contract ISwapper _swapper) public 72 | ``` 73 | 74 | -------------------------------------------------------------------------------- /doc/dev-full/TransferHelper.md: -------------------------------------------------------------------------------- 1 | # Solidity API 2 | 3 | ## TransferHelper 4 | 5 | ### safeApprove 6 | 7 | ```solidity 8 | function safeApprove(address token, address to, uint256 value) internal 9 | ``` 10 | 11 | ### safeTransfer 12 | 13 | ```solidity 14 | function safeTransfer(address token, address to, uint256 value) internal 15 | ``` 16 | 17 | ### safeTransferFrom 18 | 19 | ```solidity 20 | function safeTransferFrom(address token, address from, address to, uint256 value) internal 21 | ``` 22 | 23 | ### safeTransferETH 24 | 25 | ```solidity 26 | function safeTransferETH(address to, uint256 value) internal 27 | ``` 28 | 29 | -------------------------------------------------------------------------------- /doc/dev-full/UnitProxy.md: -------------------------------------------------------------------------------- 1 | # Solidity API 2 | 3 | ## UnitProxy 4 | 5 | ### constructor 6 | 7 | ```solidity 8 | constructor(address _logic, address admin_, bytes _data) public payable 9 | ``` 10 | 11 | -------------------------------------------------------------------------------- /doc/dev-full/WSSLPUserProxy.md: -------------------------------------------------------------------------------- 1 | # Solidity API 2 | 3 | ## WSSLPUserProxy 4 | 5 | ### manager 6 | 7 | ```solidity 8 | address manager 9 | ``` 10 | 11 | ### topDog 12 | 13 | ```solidity 14 | contract ITopDog topDog 15 | ``` 16 | 17 | ### topDogPoolId 18 | 19 | ```solidity 20 | uint256 topDogPoolId 21 | ``` 22 | 23 | ### boneToken 24 | 25 | ```solidity 26 | contract IERC20 boneToken 27 | ``` 28 | 29 | ### onlyManager 30 | 31 | ```solidity 32 | modifier onlyManager() 33 | ``` 34 | 35 | ### constructor 36 | 37 | ```solidity 38 | constructor(contract ITopDog _topDog, uint256 _topDogPoolId) public 39 | ``` 40 | 41 | ### approveSslpToTopDog 42 | 43 | ```solidity 44 | function approveSslpToTopDog(contract IERC20 _sslpToken) public 45 | ``` 46 | 47 | _in case of change sslp_ 48 | 49 | ### deposit 50 | 51 | ```solidity 52 | function deposit(uint256 _amount) public 53 | ``` 54 | 55 | ### withdraw 56 | 57 | ```solidity 58 | function withdraw(contract IERC20 _sslpToken, uint256 _amount, address _sentTokensTo) public 59 | ``` 60 | 61 | ### pendingReward 62 | 63 | ```solidity 64 | function pendingReward(address _feeReceiver, uint8 _feePercent) public view returns (uint256) 65 | ``` 66 | 67 | ### claimReward 68 | 69 | ```solidity 70 | function claimReward(address _user, address _feeReceiver, uint8 _feePercent) public 71 | ``` 72 | 73 | ### _calcFee 74 | 75 | ```solidity 76 | function _calcFee(uint256 _amount, address _feeReceiver, uint8 _feePercent) internal pure returns (uint256 amountWithoutFee, uint256 fee) 77 | ``` 78 | 79 | ### _sendAllBonesToUser 80 | 81 | ```solidity 82 | function _sendAllBonesToUser(address _user, address _feeReceiver, uint8 _feePercent) internal 83 | ``` 84 | 85 | ### _sendBonesToUser 86 | 87 | ```solidity 88 | function _sendBonesToUser(address _user, uint256 _amount, address _feeReceiver, uint8 _feePercent) internal 89 | ``` 90 | 91 | ### getClaimableRewardFromBoneLocker 92 | 93 | ```solidity 94 | function getClaimableRewardFromBoneLocker(contract IBoneLocker _boneLocker, address _feeReceiver, uint8 _feePercent) public view returns (uint256) 95 | ``` 96 | 97 | ### claimRewardFromBoneLocker 98 | 99 | ```solidity 100 | function claimRewardFromBoneLocker(address _user, contract IBoneLocker _boneLocker, uint256 _maxBoneLockerRewardsAtOneClaim, address _feeReceiver, uint8 _feePercent) public 101 | ``` 102 | 103 | ### emergencyWithdraw 104 | 105 | ```solidity 106 | function emergencyWithdraw() public 107 | ``` 108 | 109 | ### withdrawToken 110 | 111 | ```solidity 112 | function withdrawToken(address _token, address _user, uint256 _amount, address _feeReceiver, uint8 _feePercent) public 113 | ``` 114 | 115 | ### readBoneLocker 116 | 117 | ```solidity 118 | function readBoneLocker(address _boneLocker, bytes _callData) public view returns (bool success, bytes data) 119 | ``` 120 | 121 | ### callBoneLocker 122 | 123 | ```solidity 124 | function callBoneLocker(address _boneLocker, bytes _callData) public returns (bool success, bytes data) 125 | ``` 126 | 127 | ### getDepositedAmount 128 | 129 | ```solidity 130 | function getDepositedAmount() public view returns (uint256 amount) 131 | ``` 132 | 133 | -------------------------------------------------------------------------------- /doc/dev-full/WrappedToUnderlyingOracle.md: -------------------------------------------------------------------------------- 1 | # Solidity API 2 | 3 | ## WrappedToUnderlyingOracle 4 | 5 | _Oracle to quote wrapped tokens to underlying_ 6 | 7 | ### oracleRegistry 8 | 9 | ```solidity 10 | contract IOracleRegistry oracleRegistry 11 | ``` 12 | 13 | ### assetToUnderlying 14 | 15 | ```solidity 16 | mapping(address => address) assetToUnderlying 17 | ``` 18 | 19 | ### NewUnderlying 20 | 21 | ```solidity 22 | event NewUnderlying(address wrapped, address underlying) 23 | ``` 24 | 25 | ### constructor 26 | 27 | ```solidity 28 | constructor(address _vaultParameters, address _oracleRegistry) public 29 | ``` 30 | 31 | ### setUnderlying 32 | 33 | ```solidity 34 | function setUnderlying(address wrapped, address underlying) external 35 | ``` 36 | 37 | ### assetToUsd 38 | 39 | ```solidity 40 | function assetToUsd(address asset, uint256 amount) public view returns (uint256) 41 | ``` 42 | 43 | ### _getOracleAndUnderlying 44 | 45 | ```solidity 46 | function _getOracleAndUnderlying(address asset) internal view returns (address oracle, address underlying) 47 | ``` 48 | 49 | -------------------------------------------------------------------------------- /doc/dev-full/WrappedToUnderlyingOracleKeydonix.md: -------------------------------------------------------------------------------- 1 | # Solidity API 2 | 3 | ## WrappedToUnderlyingOracleKeydonix 4 | 5 | _Oracle to quote wrapped tokens to underlying_ 6 | 7 | ### oracleRegistry 8 | 9 | ```solidity 10 | contract IOracleRegistry oracleRegistry 11 | ``` 12 | 13 | ### assetToUnderlying 14 | 15 | ```solidity 16 | mapping(address => address) assetToUnderlying 17 | ``` 18 | 19 | ### NewUnderlying 20 | 21 | ```solidity 22 | event NewUnderlying(address wrapped, address underlying) 23 | ``` 24 | 25 | ### constructor 26 | 27 | ```solidity 28 | constructor(address _vaultParameters, address _oracleRegistry) public 29 | ``` 30 | 31 | ### setUnderlying 32 | 33 | ```solidity 34 | function setUnderlying(address wrapped, address underlying) external 35 | ``` 36 | 37 | ### assetToUsd 38 | 39 | ```solidity 40 | function assetToUsd(address asset, uint256 amount, struct KeydonixOracleAbstract.ProofDataStruct proofData) public view returns (uint256) 41 | ``` 42 | 43 | ### _getOracleAndUnderlying 44 | 45 | ```solidity 46 | function _getOracleAndUnderlying(address asset) internal view returns (address oracle, address underlying) 47 | ``` 48 | 49 | _for saving gas not checking underlying oracle for keydonix type since call to online oracle will fail anyway_ 50 | 51 | -------------------------------------------------------------------------------- /doc/dev-full/WstEthOracle.md: -------------------------------------------------------------------------------- 1 | # Solidity API 2 | 3 | ## WstEthOracle 4 | 5 | _Wrapper to quote wstETH ERC20 token that represents the account's share of the total supply of stETH tokens. https://docs.lido.fi/contracts/wsteth/_ 6 | 7 | ### oracleRegistry 8 | 9 | ```solidity 10 | contract IOracleRegistry oracleRegistry 11 | ``` 12 | 13 | ### stEthPriceFeed 14 | 15 | ```solidity 16 | address stEthPriceFeed 17 | ``` 18 | 19 | ### stEthDecimals 20 | 21 | ```solidity 22 | uint256 stEthDecimals 23 | ``` 24 | 25 | ### wstETH 26 | 27 | ```solidity 28 | address wstETH 29 | ``` 30 | 31 | ### addressWETH 32 | 33 | ```solidity 34 | address addressWETH 35 | ``` 36 | 37 | ### MAX_SAFE_PRICE_DIFF 38 | 39 | ```solidity 40 | uint256 MAX_SAFE_PRICE_DIFF 41 | ``` 42 | 43 | ### StEthPriceFeedChanged 44 | 45 | ```solidity 46 | event StEthPriceFeedChanged(address implementation) 47 | ``` 48 | 49 | ### constructor 50 | 51 | ```solidity 52 | constructor(address _vaultParameters, address _oracleRegistry, address _wstETH, address _stETHPriceFeed) public 53 | ``` 54 | 55 | ### setStEthPriceFeed 56 | 57 | ```solidity 58 | function setStEthPriceFeed(address impl) external 59 | ``` 60 | 61 | ### getDecimalsStEth 62 | 63 | ```solidity 64 | function getDecimalsStEth() public view returns (uint256) 65 | ``` 66 | 67 | ### assetToUsd 68 | 69 | ```solidity 70 | function assetToUsd(address bearing, uint256 amount) public view returns (uint256) 71 | ``` 72 | 73 | -------------------------------------------------------------------------------- /doc/dev-full/YvTokenOracle.md: -------------------------------------------------------------------------------- 1 | # Solidity API 2 | 3 | ## YvTokenOracle 4 | 5 | _Wrapper to quote V2 yVault Tokens like yvWETH, yvDAI, yvUSDC, yvUSDT 6 | yVault Tokens list: https://docs.yearn.finance/yearn-finance/yvaults/vault-tokens#v2-yvault-tokens_ 7 | 8 | ### oracleRegistry 9 | 10 | ```solidity 11 | contract IOracleRegistry oracleRegistry 12 | ``` 13 | 14 | ### constructor 15 | 16 | ```solidity 17 | constructor(address _vaultParameters, address _oracleRegistry) public 18 | ``` 19 | 20 | ### assetToUsd 21 | 22 | ```solidity 23 | function assetToUsd(address bearing, uint256 amount) public view returns (uint256) 24 | ``` 25 | 26 | ### bearingToUnderlying 27 | 28 | ```solidity 29 | function bearingToUnderlying(address bearing, uint256 amount) public view returns (address, uint256) 30 | ``` 31 | 32 | -------------------------------------------------------------------------------- /doc/dev/CDPManager.md: -------------------------------------------------------------------------------- 1 | # CDPManager01 Smart Contract Technical Overview 2 | 3 | ## Contract Overview 4 | `CDPManager01` is a smart contract in the Unit Protocol system designed to manage Collateralized Debt Positions (CDPs). It allows users to deposit collateral, borrow USDP (the protocol's stablecoin), and manage their positions. 5 | 6 | ## Key Features 7 | 8 | ### 1. Contract Dependencies 9 | - Interfaces with multiple contracts like `IVault`, `IVaultParameters`, `IOracleRegistry`, `ICDPRegistry`, `IVaultManagerParameters`, and `IVaultManagerBorrowFeeParameters`. 10 | - Uses `WETH` as the Ethereum wrapped token. 11 | 12 | ### 2. Main Functionalities 13 | - **Deposit Collateral and Borrow USDP:** Users can deposit an ERC20 token as collateral and borrow USDP against it. 14 | - **Repay Debt and Withdraw Collateral:** Users can repay borrowed USDP and withdraw their collateral. 15 | - **Join and Exit with Leverage:** Users can create a leveraged position by depositing collateral and borrowing USDP in one transaction with the help of a flash loan, and vice versa. 16 | - **Wrapped Asset Support:** Users can deposit collateral as a wrapped asset (e.g., staking tokens) and borrow against it. 17 | 18 | ### 3. Liquidation 19 | - **Trigger Liquidation:** Any user can trigger the liquidation of an undercollateralized position. 20 | 21 | ### 4. Utility Functions 22 | - **Collateralization Checks:** The contract includes functions to ensure and check if a position is sufficiently collateralized. 23 | - **Utilization Ratio Calculation:** Calculate the utilization ratio of a position. 24 | - **Liquidation Check:** Check if a position is liquidatable. 25 | 26 | ### 5. Modifiers 27 | - **nonReentrant:** Prevents reentrant calls to critical functions. 28 | - **checkpoint:** Records a checkpoint in the CDP registry. 29 | 30 | ### 6. Events 31 | - Several events for tracking various activities like `Join`, `Exit`, `JoinWithLeverage`, `ExitWithDeleverage`, and `LiquidationTriggered`. 32 | 33 | ### 7. Error Handling 34 | - Includes checks for valid transactions, sufficient collateralization, and avoids unnecessary transactions. 35 | 36 | ### 8. External Interfaces 37 | - The contract interacts with external oracles for price feeds and utilizes swappers for asset exchanges. 38 | 39 | ## Conclusion 40 | `CDPManager01` serves as a comprehensive management tool for handling collateralized debt positions within the Unit Protocol ecosystem. It offers features for depositing collateral, borrowing, repayment, and liquidation, along with additional utilities for position management. 41 | -------------------------------------------------------------------------------- /doc/dev/CollateralRegistry.md: -------------------------------------------------------------------------------- 1 | # CollateralRegistry Smart Contract Overview 2 | 3 | The `CollateralRegistry` smart contract is designed for managing approved collateral assets in the Unit Protocol. It enables the tracking and modification of collateral assets within the protocol. 4 | 5 | ## Key Components and Features 6 | 7 | ### 1. Inheritance 8 | - Inherits from the `Auth` contract for permissions and access control. 9 | 10 | ### 2. Events 11 | - **CollateralAdded**: Emitted when a new collateral asset is added to the registry. 12 | - **CollateralRemoved**: Emitted when a collateral asset is removed from the registry. 13 | 14 | ### 3. State Variables 15 | - **collateralId**: Maps an asset address to its identifier. 16 | - **collateralList**: An array storing addresses of the collateral assets. 17 | 18 | ### 4. Constructor 19 | - Initializes the contract with a list of collateral assets, adding them to the `collateralList` and assigning identifiers in `collateralId`. 20 | 21 | ### 5. Collateral Management Functions 22 | - **addCollateral**: Adds a new asset to the collateral list, ensuring the asset isn't already listed and the address is valid. 23 | - **removeCollateral**: Removes an existing asset from the collateral list, after confirming its presence. 24 | 25 | ### 6. Utility Functions 26 | - **isCollateral**: Determines if an address is a listed collateral asset. 27 | - **collaterals**: Returns the complete list of collateral assets. 28 | - **collateralsCount**: Provides the total number of collateral assets in the list. 29 | 30 | ## Purpose and Use Case 31 | 32 | The `CollateralRegistry` contract is essential in the Unit Protocol ecosystem for several reasons: 33 | 34 | 1. **Risk Management**: Maintains a list of vetted assets that are permissible as collateral, aiding in risk control. 35 | 2. **Protocol Governance**: Allows protocol to adjust the collateral asset list in response to market dynamics or governance decisions. 36 | 3. **User Transparency**: Offers users clear information on permissible collateral assets, enhancing trust and clarity. 37 | 4. **Efficiency and Flexibility**: Streamlines the process of updating the list of collateral assets, ensuring the protocol's adaptability to market changes. 38 | 39 | In essence, `CollateralRegistry` is crucial for maintaining the collateral system's integrity and adaptability within the Unit Protocol, ensuring that the protocol stays responsive to asset value fluctuations and market trends. 40 | -------------------------------------------------------------------------------- /doc/dev/LiquidationAuction02.md: -------------------------------------------------------------------------------- 1 | # LiquidationAuction02 Smart Contract Technical Overview 2 | 3 | ## Contract Overview 4 | The `LiquidationAuction02` contract is focused on asset liquidation in case of collateralized debt positions (CDPs) becoming undercollateralized. It interacts with several other contracts within the system, such as `IVault`, `IVaultManagerParameters`, and `ICDPRegistry`. 5 | 6 | ## Key Features 7 | 8 | ### 1. Interfaces 9 | The contract integrates with multiple interfaces to interact with different components of the system: 10 | - `IVault` 11 | - `IVaultManagerParameters` 12 | - `ICDPRegistry` 13 | - `IAssetsBooleanParameters` 14 | 15 | ### 2. Reentrancy Guard 16 | Implements `ReentrancyGuard` to prevent reentrant calls, enhancing security especially in financial operations. 17 | 18 | ### 3. Event 19 | Defines an event `Buyout` for logging buyout details. 20 | 21 | ### 4. Constants 22 | Defines constants like `DENOMINATOR_1E2` and `WRAPPED_TO_UNDERLYING_ORACLE_TYPE` for internal calculations. 23 | 24 | ### 5. Constructor 25 | Initializes the contract with addresses of `IVaultManagerParameters`, `ICDPRegistry`, and `IAssetsBooleanParameters`. 26 | 27 | ### 6. Modifiers 28 | - `checkpoint`: Ensures updating the CDP registry after certain actions. 29 | 30 | ### 7. Main Function: `buyout` 31 | The `buyout` function allows users to buy out collateral from an undercollateralized position. 32 | - Validates that liquidation is triggered. 33 | - Calculates the buyout price and the collateral distribution between the liquidator and the original owner. 34 | - Handles special conditions for asset transfer and position movement based on asset parameters. 35 | - Interacts with `vault` to execute liquidation. 36 | 37 | ### 8. Private Functions 38 | - `_liquidate`: Internal function to facilitate liquidation logic. 39 | - `_calcLiquidationParams`: Calculates parameters for liquidation including how collateral is distributed and the repayment amount. 40 | 41 | ## Security Considerations 42 | The use of `ReentrancyGuard` suggests a focus on security, particularly against reentrancy attacks. The contract's functions interact with external contracts, necessitating careful consideration of trust assumptions and interactions. 43 | 44 | ## Conclusion 45 | `LiquidationAuction02` is a crucial part of the liquidation mechanism in a DeFi ecosystem, handling the process of liquidating undercollateralized positions by calculating and distributing assets between parties involved. 46 | -------------------------------------------------------------------------------- /doc/dev/ParametersBatchUpdater.md: -------------------------------------------------------------------------------- 1 | # ParametersBatchUpdater Smart Contract Overview 2 | 3 | The `ParametersBatchUpdater` is a smart contract in the Unit Protocol designed for efficient updates of various parameters across multiple contracts within the protocol. 4 | 5 | ## Key Components and Features 6 | 7 | ### 1. Inheritance 8 | - Inherits from the `Auth` contract for restricted access control. 9 | 10 | ### 2. State Variables 11 | - **vaultManagerParameters**: Immutable reference to IVaultManagerParameters. 12 | - **oracleRegistry**: Immutable reference to IOracleRegistry. 13 | - **collateralRegistry**: Immutable reference to ICollateralRegistry. 14 | - **BEARING_ASSET_ORACLE_TYPE**: Constant for bearing asset oracle type. 15 | 16 | ### 3. Constructor 17 | - Initializes with references to VaultManagerParameters, OracleRegistry, and CollateralRegistry contracts. 18 | 19 | ### 4. Managerial Functions 20 | - **setManagers**: Updates permissions for multiple manager addresses. 21 | - **setVaultAccesses**: Grants or revokes Vault access for multiple addresses. 22 | - **setStabilityFees**: Sets stability fees for various assets. 23 | - **setLiquidationFees**: Adjusts liquidation fees for multiple assets. 24 | - **setOracleTypes**: Toggles oracle types for specific assets. 25 | - **setTokenDebtLimits**: Modifies USDP debt limits for a range of assets. 26 | - **changeOracleTypes**: Alters oracle types for given assets and users. 27 | - **setInitialCollateralRatios**: Updates collateral ratios for various assets. 28 | - **setLiquidationRatios**: Sets new liquidation ratios for multiple assets. 29 | - **setLiquidationDiscounts**: Changes liquidation discounts for different assets. 30 | - **setDevaluationPeriods**: Adjusts devaluation periods for several assets. 31 | - **setOracleTypesInRegistry**: Updates oracle types in OracleRegistry for multiple oracles. 32 | - **setOracleTypesToAssets**: Links oracle types to specific assets. 33 | - **setOracleTypesToAssetsBatch**: Batch sets oracle types for asset arrays. 34 | - **setUnderlyings**: Defines underlying assets for bearings in the oracle. 35 | - **setCollaterals**: Configures and adds collateral parameters for asset lists. 36 | - **setCollateralAddresses**: Adds or removes assets from the collateral registry in batch. 37 | 38 | ## Purpose and Use Case 39 | 40 | `ParametersBatchUpdater` plays a vital role in managing and updating crucial parameters in the Unit Protocol. Its functions include: 41 | 42 | - Adjusting risk parameters like stability fees, liquidation fees, and collateral ratios to respond to changing market conditions and maintain protocol stability. 43 | - Managing oracle settings to ensure accurate asset price feeds. 44 | - Updating collateral assets in response to changing acceptance criteria. 45 | 46 | This contract improves efficiency in managing numerous parameters and assets, allowing the protocol to quickly adapt to new requirements or market conditions. 47 | 48 | In essence, `ParametersBatchUpdater` is a key tool for protocol governance for maintaining and updating important parameters across the Unit Protocol ecosystem. 49 | -------------------------------------------------------------------------------- /doc/dev/USDP.md: -------------------------------------------------------------------------------- 1 | # USDP Smart Contract Overview 2 | 3 | The USDP smart contract is a part of the Unit Protocol, a decentralized finance (DeFi) platform. It focuses on the USDP stablecoin, implementing ERC20 standards along with specific functionalities tailored for stablecoin operations on the Ethereum blockchain. 4 | 5 | ## Key Components and Features 6 | 7 | ### 1. Contract Inheritance 8 | - Inherits from the `Auth` contract for system access and permission management. 9 | 10 | ### 2. SafeMath Library 11 | - Uses `SafeMath` for safe arithmetic operations, safeguarding against integer overflows. 12 | 13 | ### 3. Core Attributes 14 | - `name`: "USDP Stablecoin" 15 | - `symbol`: "USDP" 16 | - `version`: Token contract version 17 | - `decimals`: 18, defining the smallest unit of the token 18 | - `totalSupply`: Tracks total USDP tokens in circulation 19 | 20 | ### 4. State Variables 21 | - `balanceOf`: Mapping of account balances 22 | - `allowance`: Mapping to manage token allowances 23 | 24 | ### 5. Contract Events 25 | - `Approval`: Emitted when `approve` is called successfully 26 | - `Transfer`: Triggered during token transfers 27 | 28 | ### 6. Constructor 29 | - Initializes the contract with system parameters 30 | 31 | ### 7. Token Minting and Burning 32 | - `mint`: Function for the Vault to mint USDP tokens 33 | - `burn`: Allows burning tokens from a manager's balance or any account by the Vault 34 | 35 | ### 8. ERC20 Standard Functions 36 | - `transfer`: Transfers tokens from the caller's account 37 | - `transferFrom`: Manages transfers considering allowances 38 | - `approve`: Sets allowances for other accounts 39 | - `increaseAllowance` and `decreaseAllowance`: Adjust allowances with granularity 40 | 41 | ### 9. Internal Functions 42 | - `_approve`: Sets allowances internally 43 | - `_burn`: Handles the burning of tokens internally 44 | 45 | The USDP smart contract is integral to the Unit Protocol's stablecoin system, enabling the creation, management, and transfer of the USDP token. It conforms to the ERC20 standard for compatibility within the Ethereum ecosystem and incorporates additional functionalities for governance and operational purposes like minting and burning tokens. 46 | -------------------------------------------------------------------------------- /doc/dev/Vault.md: -------------------------------------------------------------------------------- 1 | # Vault Smart Contract Overview 2 | 3 | This smart contract is written in Solidity for the Ethereum blockchain, designed for managing collateral, debts, and stability of the USDP stablecoin. 4 | 5 | ## Key Components and Features 6 | 7 | ### 1. SafeMath Library 8 | - A library used for safe mathematical operations to protect against integer overflows. 9 | 10 | ### 2. Auth Contract 11 | - Manages permissions, ensuring only authorized users (managers) can perform certain actions, like managing the Vault or modifying its parameters. 12 | 13 | ### 3. VaultParameters Contract 14 | - A supporting contract that stores various parameters for the Vault, such as stability fees, liquidation fees, debt limits for different tokens, and permissions for who can modify the Vault. 15 | 16 | ### 4. TransferHelper Library 17 | - Aids in safely interacting with ERC20 tokens and sending ETH. 18 | 19 | ### 5. USDP Token Contract 20 | - Represents the USDP stablecoin, implementing ERC20 token standards. Includes functions for minting and burning tokens, controlled by the Vault. 21 | 22 | ### 6. IWETH Interface 23 | - Interface for interactions with WETH (Wrapped ETH), a tokenized version of Ether. 24 | 25 | ### 7. Vault Contract 26 | - **Collateral and Debt Management**: Manages user's collateral in different tokens and tracks the corresponding debt in USDP. 27 | - **Liquidation Mechanics**: Implements functions to trigger and handle liquidation of positions that are undercollateralized. 28 | - **Stability and Liquidation Fees**: Calculates and applies fees for stability (interest) and liquidation. 29 | - **Oracle Integration**: Uses external oracles to fetch price data for various assets. Oracle types can be enabled or disabled for different assets. 30 | - **ETH Support**: Includes functionality to handle Ether, converting it to WETH for consistency in collateral management. 31 | - **Access Control**: Uses modifiers from the `Auth` contract to restrict certain functions to managers or those with Vault access. 32 | - **Utility Functions**: Functions to update parameters, deposit/withdraw collateral, borrow/repay USDP, and more. 33 | 34 | The Vault smart contract is central to the USDP stablecoin system, providing core functionalities like creating and managing positions, handling collaterals, and processing debts. Its design emphasizes security, flexibility in managing different collateral types, and robust access control for administrative actions. 35 | -------------------------------------------------------------------------------- /doc/dev/oracles/ChainlinkedOracleMainAsset.md: -------------------------------------------------------------------------------- 1 | # ChainlinkedOracleMainAsset Smart Contract Technical Overview 2 | 3 | ## Contract Overview 4 | `ChainlinkedOracleMainAsset` is a contract designed for price feed integration with Chainlink. It enables the conversion of token values to USD and ETH using Chainlink's price feeds. 5 | 6 | ## Key Features 7 | 8 | ### 1. Libraries 9 | - Uses `SafeMath` for safe mathematical operations. 10 | 11 | ### 2. State Variables 12 | - `usdAggregators`: Maps token addresses to their corresponding Chainlink USD aggregators. 13 | - `ethAggregators`: Maps token addresses to their Chainlink ETH aggregators. 14 | - `Q112`: A constant representing 2^112, used for fixed-point arithmetic. 15 | - `USD_TYPE` and `ETH_TYPE`: Constants to distinguish between USD and ETH aggregator types. 16 | - `WETH`: Immutable address of the WETH token. 17 | 18 | ### 3. Events 19 | - `NewAggregator`: Emitted when a new aggregator is set for a token. 20 | 21 | ### 4. Constructor 22 | Initializes the contract with token addresses, USD aggregators, ETH aggregators, WETH address, and VaultParameters address. 23 | 24 | ### 5. Functions 25 | - `setAggregators`: Sets USD and ETH aggregators for tokens. Only callable by the manager. 26 | - `assetToUsd`: Converts an asset amount to its USD value. Supports both direct USD and indirect via ETH conversion. 27 | - `_assetToUsd`: Internal function to convert asset to USD for assets with direct USD Chainlink aggregator. 28 | - `assetToEth`: Converts an asset amount to its ETH value. Supports direct ETH conversion and indirect via USD. 29 | - `ethToUsd`: Converts an ETH amount to its USD value using Chainlink. 30 | - `usdToEth`: Converts a USD amount to its ETH value using Chainlink. 31 | 32 | ### 6. Modifiers 33 | - `onlyManager`: Restricts function access to the manager. 34 | - `Auth`: Inherits from the `Auth` contract, providing basic authorization control functions. 35 | 36 | ### 7. Security Considerations 37 | - Ensures Chainlink data freshness by requiring the latest price update to be within a defined time window. 38 | - Protects against negative price returns from Chainlink. 39 | - Utilizes `SafeMath` for safe arithmetic operations to prevent overflows and underflows. 40 | 41 | ### 8. External Dependencies 42 | - Relies on Chainlink's price feeds to provide asset price data. 43 | - Depends on the `VaultParameters` contract for authorization checks. 44 | 45 | ## Conclusion 46 | `ChainlinkedOracleMainAsset` serves as a bridge between Chainlink's price feeds and the Unit Protocol system. It provides critical functionality for converting asset values between USD, ETH, and other ERC20 tokens, ensuring accurate and up-to-date pricing information is used in the protocol's operations. 47 | -------------------------------------------------------------------------------- /doc/dev/oracles/CurveLPOracle.md: -------------------------------------------------------------------------------- 1 | # CurveLPOracle Smart Contract Technical Overview 2 | 3 | ## Contract Overview 4 | `CurveLPOracle` is a smart contract designed to provide USD pricing for Curve Finance liquidity pool (LP) tokens. It interacts with various Curve and Chainlink interfaces to achieve this. 5 | 6 | ## Key Features 7 | 8 | ### 1. Interfaces and Libraries 9 | - Implements `IOracleUsd` for USD pricing functionality. 10 | - Uses `SafeMath` library for safe mathematical operations. 11 | - Interacts with various interfaces including `ERC20Like`, `ICurveProvider`, `ICurveRegistry`, `ICurvePool`, and `IOracleRegistry`. 12 | 13 | ### 2. State Variables 14 | - `curveProvider`: Immutable address of the Curve Provider contract. 15 | - `oracleRegistry`: Immutable address of the OracleRegistry contract. 16 | - `Q112`: A constant for Q112 encoding, representing a fixed-point number with 112 fractional bits. 17 | - `PRECISION`: A constant representing the precision level (1e18) used in calculations. 18 | 19 | ### 3. Constructor 20 | Initializes the contract with the addresses of the Curve Provider and OracleRegistry contracts. 21 | 22 | ### 4. Functions 23 | - `assetToUsd`: Main function of the contract. It takes a Curve LP token address and an amount, returning its USD price in Q112-encoded format. The function performs several checks and calculations: 24 | - Validates that the input amount is non-zero. 25 | - Retrieves the Curve pool associated with the LP token. 26 | - Checks that the LP token has standard 18 decimals. 27 | - Determines the number of coins in the Curve pool. 28 | - Iterates through each coin in the Curve pool to find the minimum USD price using registered oracles. 29 | - Calculates the USD price of the LP token based on the virtual price of the Curve pool and the minimum coin price. 30 | 31 | ### 5. Error Handling and Validation 32 | - Ensures the Curve pool address for the LP token is valid. 33 | - Validates that the LP token adheres to 18 decimals standard. 34 | - Confirms that the coins count in the Curve pool is non-zero. 35 | - Checks for the existence of a registered oracle for each coin in the Curve pool. 36 | 37 | ### 6. External Dependencies 38 | - Depends on external Curve and Chainlink contracts for fetching pool information, coin details, and USD pricing. 39 | - Utilizes OracleRegistry for determining the appropriate oracle for each coin in a Curve pool. 40 | 41 | ## Conclusion 42 | `CurveLPOracle` is a specialized oracle contract for determining the USD price of Curve LP tokens. It leverages Curve's pool mechanics and integrates with Chainlink oracles, ensuring accurate and up-to-date pricing for assets within Curve liquidity pools. 43 | -------------------------------------------------------------------------------- /doc/dev/oracles/OraclePoolToken.md: -------------------------------------------------------------------------------- 1 | # OraclePoolToken Smart Contract Technical Overview 2 | 3 | ## Contract Overview 4 | The `OraclePoolToken` contract provides a mechanism to calculate the USD price of Uniswap Liquidity Pool (LP) tokens. It utilizes other oracle services to determine asset prices and interacts with Uniswap V2 pairs. The price estimation is resistant to flash loan / sandwich attacks. 5 | 6 | ## Key Features 7 | 8 | ### 1. Libraries 9 | - Utilizes `SafeMath` for safe arithmetic operations. 10 | 11 | ### 2. Interfaces 12 | - Implements `IOracleUsd` for fetching USD price data. 13 | - Interacts with `IUniswapV2PairFull`, `IOracleEth`, and `IOracleRegistry` interfaces. 14 | 15 | ### 3. State Variables 16 | - `oracleRegistry`: Immutable address of the OracleRegistry contract. 17 | - `WETH`: Immutable address of the WETH token. 18 | - `Q112`: A constant used for Q112 encoding (2^112), which is a fixed-point arithmetic representation. 19 | 20 | ### 4. Constructor 21 | - Initializes the contract by setting the OracleRegistry address. 22 | 23 | ### 5. Main Function: `assetToUsd` 24 | - Calculates the USD price of a given Uniswap LP token amount. 25 | - Accepts the LP token address and the amount as parameters. 26 | - Determines the underlying asset of the LP token that is not WETH. 27 | - Fetches the oracle for the underlying asset and WETH. 28 | - Calculates the average and current price of the underlying asset in WETH. 29 | - Computes the estimated WETH pool amount after a hypothetical flash loan attack, to resist manipulation. 30 | - Returns the Q112 encoded USD value of the LP token amount. 31 | 32 | ### 6. Error Handling 33 | - Reverts if the LP token is not registered or if a required oracle is not found. 34 | - Ensures the underlying asset has an oracle in the OracleRegistry. 35 | - Validates that the LP token is a Uniswap V2 pair. 36 | 37 | ### 7. External Dependencies 38 | - Relies on external oracles for asset price data. 39 | - Depends on the Uniswap V2 pair contract for LP token information and reserves. 40 | 41 | ## Conclusion 42 | `OraclePoolToken` is a specialized oracle for determining the USD price of Uniswap V2 LP tokens. It incorporates a flashloan-resistant mechanism to provide reliable pricing data, leveraging external oracles and Uniswap V2 pair contract functionalities. 43 | -------------------------------------------------------------------------------- /doc/dev/oracles/OracleRegistry.md: -------------------------------------------------------------------------------- 1 | # OracleRegistry Smart Contract Technical Overview 2 | 3 | ## Contract Overview 4 | The `OracleRegistry` contract is part of the Unit Protocol system, serving as a registry for oracles. It maps assets to their respective oracle types and oracle addresses, providing a central point to manage and access oracle information. 5 | 6 | ## Key Features 7 | 8 | ### 1. Data Structures 9 | - `Oracle`: A struct containing oracle type and oracle address. 10 | - Mappings: 11 | - `oracleTypeByAsset`: Maps asset addresses to oracle type IDs. 12 | - `oracleByType`: Maps oracle type IDs to oracle addresses. 13 | - `oracleTypeByOracle`: Maps oracle addresses to oracle type IDs. 14 | - Arrays: 15 | - `keydonixOracleTypes`: Stores oracle type IDs specific to Keydonix oracles. 16 | 17 | ### 2. State Variables 18 | - `maxOracleType`: Tracks the maximum oracle type ID used. 19 | - `WETH`: Immutable address of the Wrapped Ether (WETH) token. 20 | 21 | ### 3. Events 22 | - `AssetOracle`: Emitted when an asset's oracle type is set or unset. 23 | - `OracleType`: Emitted when an oracle type is set or unset. 24 | - `KeydonixOracleTypes`: Emitted when Keydonix oracle types are set. 25 | 26 | ### 4. Modifiers 27 | - `validAddress`: Ensures the provided address is not the zero address. 28 | - `validType`: Ensures the provided oracle type is non-zero. 29 | - `onlyManager`: Ensures that only a manager can call certain functions. 30 | 31 | ### 5. Constructor 32 | - Initializes the contract with the `vaultParameters` and `WETH` addresses. 33 | 34 | ### 6. Key Functions 35 | - `setKeydonixOracleTypes`: Sets the oracle types specific to Keydonix oracles. 36 | - `setOracle`: Associates an oracle address with an oracle type. 37 | - `unsetOracle`: Removes an oracle type and its associated oracle address. 38 | - `setOracleTypeForAsset`: Sets the oracle type for a specific asset. 39 | - `setOracleTypeForAssets`: Sets the oracle type for multiple assets. 40 | - `unsetOracleForAsset`: Removes the oracle type association for an asset. 41 | - `unsetOracleForAssets`: Removes the oracle type associations for multiple assets. 42 | - `getOracles`: Retrieves all registered oracles. 43 | - `getKeydonixOracleTypes`: Retrieves all Keydonix oracle types. 44 | - `oracleByAsset`: Retrieves the oracle address for a given asset. 45 | 46 | ### 7. Access Control 47 | - Managed by "managers" who have the authority to modify oracle settings. 48 | - Leverages `Auth` and `VaultParameters` for access control mechanisms. 49 | 50 | ### 8. Error Handling 51 | - Performs checks to ensure valid oracle types and addresses are provided. 52 | - Reverts transactions with invalid inputs or unauthorized access. 53 | 54 | ## Conclusion 55 | `OracleRegistry` is a critical component of the Unit Protocol ecosystem, offering a structured and secure way to manage oracles for different assets. It enables dynamic oracle management, ensuring flexibility and up-to-date oracle information for the protocol's operations. 56 | -------------------------------------------------------------------------------- /lib/constants.js: -------------------------------------------------------------------------------- 1 | const ORACLE_TYPE_UNISWAP_V2_MAIN_ASSET_KEYDONIX = 1; 2 | const ORACLE_TYPE_UNISWAP_V2_POOL_TOKEN_KEYDONIX = 2; 3 | const ORACLE_TYPE_CHAINLINK_MAIN_ASSET = 5; 4 | const ORACLE_TYPE_WRAPPED_TO_UNDERLYING = 11; 5 | const ORACLE_TYPE_UNISWAP_V2_POOL_TOKEN = 12; 6 | const ORACLE_TYPE_WRAPPED_TO_UNDERLYING_KEYDONIX = 19; 7 | const ORACLE_TYPE_BRIDGED_USDP = 20; 8 | 9 | const KEYDONIX_ORACLES_TYPES = [ 10 | ORACLE_TYPE_UNISWAP_V2_MAIN_ASSET_KEYDONIX, 11 | ORACLE_TYPE_UNISWAP_V2_POOL_TOKEN_KEYDONIX, 12 | ORACLE_TYPE_WRAPPED_TO_UNDERLYING_KEYDONIX, 13 | ]; 14 | 15 | const PARAM_FORCE_TRANSFER_ASSET_TO_OWNER_ON_LIQUIDATION = 0; 16 | const PARAM_FORCE_MOVE_WRAPPED_ASSET_POSITION_ON_LIQUIDATION = 1; 17 | 18 | module.exports = { 19 | ORACLE_TYPE_UNISWAP_V2_MAIN_ASSET_KEYDONIX, 20 | ORACLE_TYPE_UNISWAP_V2_POOL_TOKEN_KEYDONIX, 21 | ORACLE_TYPE_CHAINLINK_MAIN_ASSET, 22 | ORACLE_TYPE_WRAPPED_TO_UNDERLYING, 23 | ORACLE_TYPE_UNISWAP_V2_POOL_TOKEN, 24 | ORACLE_TYPE_WRAPPED_TO_UNDERLYING_KEYDONIX, 25 | ORACLE_TYPE_BRIDGED_USDP, 26 | 27 | KEYDONIX_ORACLES_TYPES, 28 | 29 | PARAM_FORCE_TRANSFER_ASSET_TO_OWNER_ON_LIQUIDATION, 30 | PARAM_FORCE_MOVE_WRAPPED_ASSET_POSITION_ON_LIQUIDATION, 31 | }; 32 | -------------------------------------------------------------------------------- /lib/deployments/swappers.js: -------------------------------------------------------------------------------- 1 | const { 2 | VAULT_PARAMETERS, 3 | WETH, 4 | USDP, 5 | USDT, 6 | CURVE_USDP_3CRV_POOL, 7 | CURVE_USDP_3CRV_POOL_USDP, 8 | CURVE_USDP_3CRV_POOL_USDT, 9 | CURVE_TRICRYPTO2_POOL, 10 | CURVE_TRICRYPTO2_POOL_USDT, 11 | CURVE_TRICRYPTO2_POOL_WETH 12 | } = require("../../network_constants"); 13 | 14 | const createDeployment = async function(args) { 15 | let {deployer, vaultParameters, weth, usdp, usdt, 16 | usdp3crvPool, tricrypto2Pool, 17 | } = args; 18 | 19 | vaultParameters ??= VAULT_PARAMETERS; 20 | weth ??= WETH; 21 | usdp ??= USDP; 22 | usdt ??= USDT; 23 | usdp3crvPool ??= CURVE_USDP_3CRV_POOL; 24 | tricrypto2Pool ??= CURVE_TRICRYPTO2_POOL; 25 | 26 | const script = [ 27 | [ 28 | 'SwapperWethViaCurve', 29 | vaultParameters, weth, usdp, usdt, 30 | usdp3crvPool, tricrypto2Pool, 31 | ], 32 | [ 33 | 'SwapperUniswapV2Lp', 34 | vaultParameters, weth, usdp, 35 | 'SwapperWethViaCurve' 36 | ], 37 | ]; 38 | 39 | return script; 40 | }; 41 | 42 | 43 | module.exports = { 44 | createDeployment, 45 | }; 46 | -------------------------------------------------------------------------------- /lib/deployments/wrappedSSLP.js: -------------------------------------------------------------------------------- 1 | const createDeployment = async function(args) { 2 | const {deployer, manager, vaultParameters, topDog, topDogPoolId, feeReceiver} = args; 3 | 4 | const script = [ 5 | ['WrappedShibaSwapLp', vaultParameters, topDog, topDogPoolId, feeReceiver], 6 | ]; 7 | 8 | return script; 9 | }; 10 | 11 | 12 | module.exports = { 13 | createDeployment, 14 | }; 15 | -------------------------------------------------------------------------------- /migrations/1_initial_migration.js: -------------------------------------------------------------------------------- 1 | const Migrations = artifacts.require("Migrations"); 2 | 3 | module.exports = function(deployer, network) { 4 | deployer.deploy(Migrations); 5 | }; 6 | -------------------------------------------------------------------------------- /network_constants.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | WETH: "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2", 3 | USDT: "0xdAC17F958D2ee523a2206206994597C13D831ec7", 4 | USDP: "0x1456688345527bE1f37E9e627DA0837D6f08C925", 5 | 6 | 7 | VAULT: '0xb1cFF81b9305166ff1EFc49A129ad2AfCd7BCf19', 8 | VAULT_PARAMETERS: "0xB46F8CF42e504Efe8BEf895f848741daA55e9f1D", 9 | VAULT_MANAGER_PARAMETERS: '0x203153522B9EAef4aE17c6e99851EE7b2F7D312E', 10 | VAULT_MANAGER_BORROW_FEE_PARAMETERS: "0xCbA7154bfBF898d9AB0cf0e259ABAB6CcbfB4894", 11 | 12 | 13 | CDP_REGISTRY: '0x1a5Ff58BC3246Eb233fEA20D32b79B5F01eC650c', 14 | 15 | 16 | ORACLE_REGISTRY: '0x75fBFe26B21fd3EA008af0C764949f8214150C8f', 17 | ORACLE_CHAINLINK: "0x54b21C140F5463e1fDa69B934da619eAaa61f1CA", // ChainlinkedOracleMainAsset 18 | ORACLE_POOL_TOKEN: "0xd88e1F40b6CD9793aa10A6C3ceEA1d01C2a507f9", // OraclePoolToken 19 | 20 | 21 | CURVE_USDP_3CRV_POOL: "0x42d7025938bEc20B69cBae5A77421082407f053A", 22 | CURVE_TRICRYPTO2_POOL: "0xD51a44d3FaE010294C616388b506AcdA1bfAAE46", 23 | } 24 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "usdp-contracts", 3 | "version": "0.0.1", 4 | "main": "index.js", 5 | "author": "@bcngod", 6 | "license": "SEE LICENSE IN LICENSE", 7 | "scripts": { 8 | "test": "truffle test", 9 | "test:curve": "truffle test test/CDPManager_WrappedAssets.test.js test/LiquidationTrigger_WrappedAssets.test.js test/LiquidationAuction.test.js", 10 | "test:single-point": "truffle test test/*Keep3r*.test.js test/*Wrapped*.test.js test/Li*Bearing*.test.js test/CDP*Bearing*.test.js test/LiquidationAuction.test.js test/LiquidationTrigger_Chainlink.test.js test/LiquidationTrigger_PoolToken_Chainlink.test.js", 11 | "test:cytoken": "truffle test test/CyTokenOracle.test.js", 12 | "test:yvtoken": "truffle test test/YvTokenOracle.test.js", 13 | "test:wsteth": "truffle test test/WstEthOracle.test.js", 14 | "build": "rm -rf build && truffle compile", 15 | "coverage": "truffle run coverage", 16 | "fast-test": "npx hardhat test" 17 | }, 18 | "dependencies": { 19 | "@keydonix/uniswap-oracle-contracts": "^1.0.0", 20 | "@keydonix/uniswap-oracle-sdk": "^1.0.1", 21 | "@nomiclabs/hardhat-ethers": "^2.0.2", 22 | "@nomiclabs/hardhat-etherscan": "^2.1.6", 23 | "@nomiclabs/hardhat-truffle5": "^2.0.2", 24 | "@nomiclabs/hardhat-waffle": "^2.0.1", 25 | "@nomiclabs/hardhat-web3": "^2.0.0", 26 | "@openzeppelin/contracts": "3.4.0", 27 | "@truffle/hdwallet-provider": "^1.5.1", 28 | "chai": "^4.2.0", 29 | "chai-arrays": "^2.2.0", 30 | "dotenv": "^8.2.0", 31 | "ethereum-waffle": "^3.4.0", 32 | "ethers": "^5.4.7", 33 | "find-config": "^1.0.0", 34 | "hardhat": "^2.6.4", 35 | "hardhat-gas-reporter": "^1.0.4", 36 | "hardhat-local-networks-config-plugin": "0.0.6", 37 | "openzeppelin-test-helpers": "^0.5.1", 38 | "rlp": "^2.2.5", 39 | "solc": "0.7.4", 40 | "solidity-docgen": "^0.5.4", 41 | "truffle": "^5.4.11", 42 | "truffle-hdwallet-provider": "^1.0.17", 43 | "truffle-privatekey-provider": "^1.3.0" 44 | }, 45 | "devDependencies": { 46 | "solidity-coverage": "^0.7.9" 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /test/BearingAssetsOracle.test.js: -------------------------------------------------------------------------------- 1 | const BN = web3.utils.BN 2 | const { expect } = require('chai') 3 | const utils = require('./helpers/utils') 4 | 5 | const Q112 = new BN('2').pow(new BN('112')) 6 | 7 | contract('BearingAssetsOracle', function([ 8 | account1, 9 | ]) { 10 | // deploy & initial settings 11 | beforeEach(async function() { 12 | this.utils = utils(this, 'bearingAssetSimple') 13 | this.deployer = account1 14 | await this.utils.deploy() 15 | }); 16 | 17 | it('Should quote bearing asset', async function () { 18 | const supply = await this.bearingAsset.totalSupply() 19 | 20 | const reserve = supply.mul(new BN('2')) 21 | await this.mainCollateral.transfer(this.bearingAsset.address, reserve) 22 | 23 | const rate = await this.bearingAssetOracle.bearingToUnderlying(this.bearingAsset.address, 1) 24 | 25 | expect(rate[0]).to.equal(this.mainCollateral.address) 26 | expect(rate[1]).to.be.bignumber.equal(reserve.div(supply)); 27 | 28 | const usd_q112 = await this.bearingAssetOracle.assetToUsd(this.bearingAsset.address, supply); 29 | 30 | // since 1 main collateral token costs 2$ 31 | const expectedUsdValue_q112 = reserve.mul(Q112).mul(new BN('2')) 32 | 33 | expect(usd_q112).to.be.bignumber.equal(expectedUsdValue_q112); 34 | 35 | }) 36 | }); 37 | -------------------------------------------------------------------------------- /test/CurveLPOracle.test.js: -------------------------------------------------------------------------------- 1 | const BN = web3.utils.BN 2 | const { expect } = require('chai') 3 | const utils = require('./helpers/utils') 4 | 5 | const Q112 = new BN('2').pow(new BN('112')) 6 | 7 | contract('CurveLPOracle', function([ 8 | account1, 9 | ]) { 10 | // deploy & initial settings 11 | beforeEach(async function() { 12 | this.utils = utils(this, 'curveLP') 13 | this.deployer = account1 14 | await this.utils.deploy() 15 | }); 16 | 17 | it('Should quote curve lp', async function () { 18 | 19 | const usd_q112 = await this.wrappedToUnderlyingOracle.assetToUsd(this.wrappedAsset.address, 1); 20 | 21 | // since 1 virtual price is 1$ 22 | expect(usd_q112).to.be.bignumber.equal(Q112); 23 | 24 | }) 25 | }); 26 | -------------------------------------------------------------------------------- /test/CyTokenOracle.test.js: -------------------------------------------------------------------------------- 1 | const BN = web3.utils.BN 2 | const { expect } = require('chai') 3 | const utils = require('./helpers/utils') 4 | 5 | const Q112 = new BN('2').pow(new BN('112')) 6 | 7 | contract('CyTokenOracle', function([account1]) { 8 | // deploy & initial settings 9 | beforeEach(async function() { 10 | this.utils = utils(this, 'cyWETHsample') 11 | this.deployer = account1 12 | await this.utils.deploy() 13 | }); 14 | 15 | it('Should check that the implementation of cyWETH is enabled', async function () { 16 | const tokenImplementation = await this.cyWETH.implementation(); 17 | const isEnabled = await this.CyTokenOracle.enabledImplementations(tokenImplementation); 18 | expect(isEnabled).to.equal(true); 19 | }); 20 | 21 | it('Should check that underlying of cyWETH equal to WETH address', async function () { 22 | const underlying = await this.cyWETH.underlying(); 23 | expect(underlying).to.equal(this.weth.address); 24 | }); 25 | 26 | let cyWETHamount = 20000000000; 27 | 28 | it('Should check that cyWETH totalSupply not less then cyWETH amount', async function () { 29 | const supply = await this.cyWETH.totalSupply(); 30 | expect(!(supply < cyWETHamount)).to.be.true; 31 | }); 32 | 33 | it('Should quote cyWETH', async function () { 34 | const rate = await this.CyTokenOracle.bearingToUnderlying(this.cyWETH.address, cyWETHamount); 35 | // since 1 WETH token costs 250$ 36 | const expectedUsdValue_q112 = rate[1].mul(Q112).mul(new BN('250')); 37 | const usd_q112 = await this.CyTokenOracle.assetToUsd(this.cyWETH.address, cyWETHamount); 38 | expect(usd_q112).to.be.bignumber.equal(expectedUsdValue_q112); 39 | }); 40 | }); 41 | -------------------------------------------------------------------------------- /test/LiquidationTrigger_Chainlink.test.js: -------------------------------------------------------------------------------- 1 | const { 2 | expectEvent, 3 | ether 4 | } = require('openzeppelin-test-helpers'); 5 | const BN = web3.utils.BN; 6 | const { expect } = require('chai'); 7 | const { nextBlockNumber } = require('./helpers/time'); 8 | const utils = require('./helpers/utils'); 9 | 10 | contract('LiquidationTriggerChainlinkMainAsset', function([ 11 | positionOwner, 12 | liquidator, 13 | ]) { 14 | // deploy & initial settings 15 | beforeEach(async function() { 16 | this.utils = utils(this, 'chainlinkMainAsset'); 17 | this.deployer = positionOwner; 18 | await this.utils.deploy(); 19 | }); 20 | 21 | it('Should trigger liquidation of undercollateralized position', async function () { 22 | const mainAmount = ether('60'); 23 | const usdpAmount = ether('70'); 24 | 25 | /* 26 | * Spawned position params: 27 | * collateral value = 60 * 2 = 120$ 28 | * utilization percent = 70 / 120 = 58.3% 29 | */ 30 | await this.utils.join(this.mainCollateral, mainAmount, usdpAmount); 31 | 32 | const newPriceOfMainInUsd = 1.301e8 33 | await this.mainUsd.setPrice(newPriceOfMainInUsd); 34 | 35 | /* 36 | * Position params after price change: 37 | * collateral value = 60 * 1.301 = ~78.06$ 38 | * utilization percent = 70 / 78.06 = ~89.67% 39 | */ 40 | 41 | const expectedLiquidationBlock = await nextBlockNumber(); 42 | 43 | const totalCollateralUsdValue = mainAmount.mul(new BN(newPriceOfMainInUsd)).div(new BN(1e8)); 44 | const initialDiscount = await this.vaultManagerParameters.liquidationDiscount(this.mainCollateral.address); 45 | const expectedLiquidationPrice = totalCollateralUsdValue.sub(totalCollateralUsdValue.mul(initialDiscount).div(new BN(1e5))); 46 | 47 | const { logs } = await this.utils.triggerLiquidation(this.mainCollateral, positionOwner, liquidator); 48 | expectEvent.inLogs(logs, 'LiquidationTriggered', { 49 | asset: this.mainCollateral.address, 50 | owner: positionOwner, 51 | }); 52 | 53 | const liquidationBlock = await this.vault.liquidationBlock(this.mainCollateral.address, positionOwner); 54 | const liquidationPrice = await this.vault.liquidationPrice(this.mainCollateral.address, positionOwner); 55 | 56 | expect(liquidationBlock).to.be.bignumber.equal(expectedLiquidationBlock); 57 | expect(liquidationPrice).to.be.bignumber.equal(expectedLiquidationPrice); 58 | }) 59 | 60 | it('Should fail to trigger liquidation of collateralized position', async function () { 61 | const mainAmount = ether('60'); 62 | const usdpAmount = ether('70'); 63 | 64 | /* 65 | * Spawned position params: 66 | * collateral value = 60 * 2 = 120$ 67 | * utilization percent = 70 / 120 = 58.3% 68 | */ 69 | await this.utils.join(this.mainCollateral, mainAmount, usdpAmount); 70 | 71 | const tx = this.utils.triggerLiquidation(this.mainCollateral, positionOwner, liquidator); 72 | await this.utils.expectRevert(tx, "Unit Protocol: SAFE_POSITION"); 73 | }) 74 | }); 75 | -------------------------------------------------------------------------------- /test/LiquidationTrigger_WrappedAssets.test.js: -------------------------------------------------------------------------------- 1 | const { 2 | expectEvent, 3 | ether 4 | } = require('openzeppelin-test-helpers') 5 | const BN = web3.utils.BN 6 | const { expect } = require('chai') 7 | const { nextBlockNumber } = require('./helpers/time') 8 | const utils = require('./helpers/utils') 9 | 10 | contract('LiquidationTriggerSimple', function([ 11 | positionOwner, 12 | liquidator, 13 | foundation, 14 | ]) { 15 | // deploy & initial settings 16 | beforeEach(async function() { 17 | this.utils = utils(this, 'curveLP') 18 | this.deployer = positionOwner 19 | this.foundation = foundation 20 | await this.utils.deploy() 21 | }); 22 | 23 | it('Should trigger liquidation of undercollateralized position', async function () { 24 | await this.curvePool.setPool(ether('1.2'), [this.curveLockedAsset1.address, this.curveLockedAsset2.address, this.curveLockedAsset3.address]) 25 | const mainAmount = ether('1000'); 26 | const usdpAmount = ether('700'); 27 | 28 | /* 29 | * Spawned position params: 30 | * utilization percent = 700 / 1200 = ~58.33% 31 | */ 32 | await this.utils.join(this.wrappedAsset, mainAmount, usdpAmount); 33 | 34 | await this.curvePool.setPool(ether('1'), [this.curveLockedAsset1.address, this.curveLockedAsset2.address, this.curveLockedAsset3.address]) 35 | 36 | const mainUsdValueAfterDump = ether('1000') 37 | 38 | /* 39 | * Position params after price change: 40 | * utilization percent = 700 / 1000 = 70% 41 | */ 42 | 43 | const expectedLiquidationBlock = await nextBlockNumber(); 44 | 45 | const totalCollateralUsdValue = mainUsdValueAfterDump; 46 | const initialDiscount = await this.vaultManagerParameters.liquidationDiscount(this.wrappedAsset.address); 47 | const expectedLiquidationPrice = totalCollateralUsdValue.sub(totalCollateralUsdValue.mul(initialDiscount).div(new BN(1e5))); 48 | 49 | const { logs } = await this.utils.triggerLiquidation(this.wrappedAsset, positionOwner, liquidator); 50 | expectEvent.inLogs(logs, 'LiquidationTriggered', { 51 | asset: this.wrappedAsset.address, 52 | owner: positionOwner, 53 | }); 54 | 55 | const liquidationBlock = await this.vault.liquidationBlock(this.wrappedAsset.address, positionOwner); 56 | const liquidationPrice = await this.vault.liquidationPrice(this.wrappedAsset.address, positionOwner); 57 | 58 | expect(liquidationBlock).to.be.bignumber.equal(expectedLiquidationBlock); 59 | expect(liquidationPrice).to.be.bignumber.equal(expectedLiquidationPrice); 60 | }) 61 | 62 | it('Should fail to trigger liquidation of collateralized position', async function () { 63 | const mainAmount = ether('50'); 64 | const usdpAmount = ether('25'); 65 | 66 | /* 67 | * Spawned position params: 68 | * collateral value = 50$ 69 | * utilization percent = 50% 70 | */ 71 | await this.utils.join(this.wrappedAsset, mainAmount, usdpAmount); 72 | 73 | const tx = this.utils.triggerLiquidation(this.wrappedAsset, positionOwner, liquidator); 74 | await this.utils.expectRevert(tx, "Unit Protocol: SAFE_POSITION"); 75 | }) 76 | }); 77 | -------------------------------------------------------------------------------- /test/YvTokenOracle.test.js: -------------------------------------------------------------------------------- 1 | const BN = web3.utils.BN 2 | const { expect } = require('chai') 3 | const utils = require('./helpers/utils') 4 | 5 | const Q112 = new BN('2').pow(new BN('112')) 6 | 7 | contract('YvTokenOracle', function([ 8 | account1, 9 | ]) { 10 | // deploy & initial settings 11 | beforeEach(async function() { 12 | this.utils = utils(this, 'yvWETHsample') 13 | this.deployer = account1 14 | await this.utils.deploy() 15 | }); 16 | 17 | it('Should check that yvWETH underlying token is equal WETH address', async function () { 18 | const underlyingAddress = await this.weth.address; 19 | const yvWethUnderlyingAddress = await this.yvWETH.token(); 20 | expect(yvWethUnderlyingAddress).to.equal(underlyingAddress); 21 | }); 22 | 23 | let yvWETHamount = 1000000; 24 | 25 | it('Should check that yvWETH totalSupply not less then yvWETH amount', async function () { 26 | const supply = await this.yvWETH.totalSupply(); 27 | expect(!(supply < yvWETHamount)).to.be.true; 28 | }); 29 | 30 | it('Should quote yvWETH', async function () { 31 | const pricePerShare = await this.yvWETH.pricePerShare(); 32 | console.log('pricePerShare: ',pricePerShare.toString(10)); 33 | const decimals = await this.yvWETH.decimals(); 34 | console.log('decimals: ',decimals.toString(10)); 35 | console.log('yvWETHamount: ', yvWETHamount); 36 | const rate = await this.YvTokenOracle.bearingToUnderlying(this.yvWETH.address, yvWETHamount); 37 | console.log('quoted yvWETHamount:', rate[1].toString(10)); 38 | // since 1 WETH token costs 250$ 39 | const expectedUsdValue_q112 = rate[1].mul(Q112).mul(new BN('250')); 40 | const usd_q112 = await this.YvTokenOracle.assetToUsd(this.yvWETH.address, yvWETHamount); 41 | expect(usd_q112).to.be.bignumber.equal(expectedUsdValue_q112); 42 | }); 43 | 44 | }); 45 | -------------------------------------------------------------------------------- /test/helpers/balances.js: -------------------------------------------------------------------------------- 1 | const BN = web3.utils.BN; 2 | 3 | async function balanceCurrent (account) { 4 | return new BN(await web3.eth.getBalance(account)); 5 | } 6 | 7 | async function balanceDifference (account, promiseFunc) { 8 | const balanceBefore = new BN(await web3.eth.getBalance(account)); 9 | await promiseFunc; 10 | const balanceAfter = new BN(await web3.eth.getBalance(account)); 11 | 12 | return balanceAfter.gt(balanceBefore) ? balanceAfter.sub(balanceBefore) : balanceBefore.sub(balanceAfter); 13 | } 14 | 15 | async function differenceExcludeGas (account, promiseFunc, gasPrice) { 16 | const balanceBefore = new BN(await web3.eth.getBalance(account)); 17 | let tx = await promiseFunc; 18 | let gas = new BN(tx.receipt.gasUsed).mul(gasPrice); 19 | const balanceAfter = new BN(await web3.eth.getBalance(account)).add(gas); 20 | return balanceAfter.gt(balanceBefore) ? balanceAfter.sub(balanceBefore) : balanceBefore.sub(balanceAfter); 21 | } 22 | 23 | module.exports = { 24 | current: balanceCurrent, 25 | difference: balanceDifference, 26 | differenceExcludeGas: differenceExcludeGas, 27 | }; 28 | -------------------------------------------------------------------------------- /test/helpers/decodeLogs.js: -------------------------------------------------------------------------------- 1 | const SolidityEvent = require('web3'); 2 | 3 | function decodeLogs (logs, contract, address) { 4 | return logs.map(log => { 5 | const event = new SolidityEvent(null, contract.events[log.topics[0]], address); 6 | return event.decode(log); 7 | }); 8 | } 9 | 10 | module.exports = { 11 | decodeLogs, 12 | }; -------------------------------------------------------------------------------- /test/helpers/ethersUtils.js: -------------------------------------------------------------------------------- 1 | const {ethers} = require("hardhat"); 2 | 3 | async function attachContract(contract, address) { 4 | return ethers.getContractAt(contract, address) 5 | } 6 | 7 | async function deployContract(contract, ...args) { 8 | const ContractFactory = await ethers.getContractFactory(contract); 9 | const deployedContract = await ContractFactory.deploy(...args); 10 | await deployedContract.deployed(); 11 | 12 | return deployedContract; 13 | } 14 | 15 | function getRandomSigner() { 16 | return new ethers.Wallet(ethers.Wallet.createRandom().privateKey, ethers.provider); 17 | } 18 | 19 | const ether = ethers.utils.parseEther; 20 | const weiToEther = wei => ethers.utils.formatUnits(wei, "ether"); 21 | const BN = ethers.BigNumber.from 22 | const Q112 = BN('2').pow(BN('112')); 23 | 24 | module.exports = { 25 | attachContract, 26 | deployContract, 27 | getRandomSigner, 28 | 29 | ether, 30 | weiToEther, 31 | BN, 32 | Q112 33 | } 34 | -------------------------------------------------------------------------------- /test/helpers/sign.js: -------------------------------------------------------------------------------- 1 | const REAL_SIGNATURE_SIZE = 2 * 65; // 65 bytes in hexadecimal string legnth 2 | const PADDED_SIGNATURE_SIZE = 2 * 96; // 96 bytes in hexadecimal string length 3 | 4 | const DUMMY_SIGNATURE = `0x${web3.utils.padLeft( 5 | '', 6 | REAL_SIGNATURE_SIZE 7 | )}`; 8 | 9 | function toEthSignedMessageHash(messageHex) { 10 | const messageBuffer = Buffer.from(messageHex.substring(2), 'hex'); 11 | const prefix = Buffer.from( 12 | `\u0019Ethereum Signed Message:\n${messageBuffer.length}` 13 | ); 14 | return web3.utils.sha3(Buffer.concat([prefix, messageBuffer])); 15 | } 16 | 17 | function fixSignature(signature) { 18 | // in geth its always 27/28, in ganache its 0/1. Change to 27/28 to prevent 19 | // signature malleability if version is 0/1 20 | // see https://github.com/ethereum/go-ethereum/blob/v1.8.23/internal/ethapi/api.go#L465 21 | let v = parseInt(signature.slice(130, 132), 16); 22 | if (v < 27) { 23 | v += 27; 24 | } 25 | const vHex = v.toString(16); 26 | return signature.slice(0, 130) + vHex; 27 | } 28 | 29 | // signs message in node (ganache auto-applies "Ethereum Signed Message" prefix) 30 | async function signMessage(signer, messageHex = '0x') { 31 | return fixSignature(await web3.eth.sign(messageHex, signer)); 32 | } 33 | 34 | /** 35 | * Create a signer between a contract and a signer for a voucher of method, args, and redeemer 36 | * Note that `method` is the web3 method, not the truffle-contract method 37 | * @param contract TruffleContract 38 | * @param signer address 39 | * @param redeemer address 40 | * @param methodName string 41 | * @param methodArgs any[] 42 | */ 43 | const getSignerFor = (contractAddress, contract, signer) => ( 44 | redeemer, 45 | methodName, 46 | methodArgs = [] 47 | ) => { 48 | const parts = [contractAddress, redeemer]; 49 | 50 | // if we have a method, add it to the parts that we're signing 51 | if (methodName) { 52 | methodArgs = methodArgs.map(arg => arg.toString()); 53 | if (methodArgs.length > 0) { 54 | parts.push( 55 | contract.contract.methods[methodName]( 56 | ...methodArgs.concat([DUMMY_SIGNATURE]) 57 | ) 58 | .encodeABI() 59 | .slice(0, -1 * PADDED_SIGNATURE_SIZE) 60 | ); 61 | } else { 62 | const abi = contract.abi.find(abi => abi.name === methodName); 63 | parts.push(abi.signature); 64 | } 65 | } 66 | 67 | // return the signature of the "Ethereum Signed Message" hash of the hash of `parts` 68 | const messageHex = web3.utils.soliditySha3(...parts); 69 | return signMessage(signer, messageHex); 70 | }; 71 | 72 | module.exports = { 73 | signMessage, 74 | toEthSignedMessageHash, 75 | fixSignature, 76 | getSignerFor 77 | }; 78 | -------------------------------------------------------------------------------- /test/helpers/time.js: -------------------------------------------------------------------------------- 1 | // Returns the time of the last mined block in seconds 2 | async function latest () { 3 | const block = await web3.eth.getBlock('latest'); 4 | return new web3.utils.BN(block.timestamp); 5 | } 6 | async function block () { 7 | const block = await web3.eth.getBlock('latest'); 8 | return new web3.utils.BN(block.number); 9 | } 10 | async function nextBlockNumber () { 11 | const block = await web3.eth.getBlock('latest'); 12 | return new web3.utils.BN(block.number).add(new web3.utils.BN('1')); 13 | } 14 | module.exports = { 15 | latest, 16 | block, 17 | nextBlockNumber, 18 | } 19 | -------------------------------------------------------------------------------- /test/helpers/timeTravel.js: -------------------------------------------------------------------------------- 1 | const increaseTime = function(duration) { 2 | const id = Date.now(); 3 | 4 | return new Promise((resolve, reject) => { 5 | web3.currentProvider.send({ 6 | jsonrpc: '2.0', 7 | method: 'evm_increaseTime', 8 | params: [duration], 9 | id: id, 10 | }, err1 => { 11 | if (err1) return reject(err1); 12 | 13 | web3.currentProvider.send({ 14 | jsonrpc: '2.0', 15 | method: 'evm_mine', 16 | id: id+1, 17 | }, (err2, res) => { 18 | return err2 ? reject(err2) : resolve(res) 19 | }) 20 | }) 21 | }) 22 | } 23 | module.exports = increaseTime -------------------------------------------------------------------------------- /test/wrapped-assets/helpers/TopDogLogic.js: -------------------------------------------------------------------------------- 1 | const {ethers} = require("ethers"); 2 | const {SHIBA_TOPDOG_BONES_PER_BLOCK, SHIBA_TOPDOG_DIRECT_BONES_USER_PERCENT} = require("../../helpers/deploy"); 3 | const {BN} = require("../../helpers/ethersUtils"); 4 | 5 | function directBonesReward(startBlock, endBlock) { 6 | return SHIBA_TOPDOG_BONES_PER_BLOCK 7 | .mul(endBlock-startBlock) 8 | .mul(SHIBA_TOPDOG_DIRECT_BONES_USER_PERCENT).div(100) 9 | .div(2) // 2 pools, divided between them 10 | ; 11 | } 12 | 13 | function lockedBonesReward(startBlock, endBlock) { 14 | return SHIBA_TOPDOG_BONES_PER_BLOCK 15 | .mul(endBlock-startBlock) 16 | .mul(BN('100').sub(SHIBA_TOPDOG_DIRECT_BONES_USER_PERCENT)).div(100) 17 | .div(2) // 2 pools, divided between them 18 | ; 19 | } 20 | 21 | function fullBonesReward(startBlock, endBlock) { 22 | return SHIBA_TOPDOG_BONES_PER_BLOCK 23 | .mul(endBlock-startBlock) 24 | .div(2) // 2 pools, divided between them 25 | ; 26 | } 27 | 28 | module.exports = { 29 | directBonesReward, 30 | lockedBonesReward, 31 | fullBonesReward 32 | } -------------------------------------------------------------------------------- /test/wrapped-assets/helpers/TopDogLogic.test.js: -------------------------------------------------------------------------------- 1 | const { expect } = require("chai"); 2 | const { ethers } = require("hardhat"); 3 | const {directBonesReward, fullBonesReward, lockedBonesReward} = require("./TopDogLogic"); 4 | const {ether} = require("../../helpers/ethersUtils"); 5 | 6 | describe("TopDogLogic", function () { 7 | [0, 1, 3, 10].forEach(blockInterval => 8 | it(`test bone reward calculation helper with interval ${blockInterval} blocks`, async function () { 9 | const expectedResult = { 10 | 0: ether('0'), 11 | 1: ether('8.25'), 12 | 3: ether('24.75'), 13 | 10: ether('82.5'), 14 | } 15 | 16 | expect(directBonesReward(10, 10+blockInterval)).to.be.equal(expectedResult[blockInterval]); 17 | expect(fullBonesReward(10, 10+blockInterval)).to.be.equal( 18 | directBonesReward(10, 10+blockInterval).add(lockedBonesReward(10, 10+blockInterval)) 19 | ); 20 | }) 21 | ); 22 | }); 23 | --------------------------------------------------------------------------------