From 3a8d9cd3936dbdfd4dc4a2f5183093f3adc84e16 Mon Sep 17 00:00:00 2001 From: Doc Akan Date: Mon, 18 Sep 2023 16:46:19 +0100 Subject: [PATCH 1/5] feat: amo facet added --- cspell.json | 3 + packages/contracts/foundry.toml | 1 - .../dollar/facets/UbiquityAMOPoolFacet.sol | 240 ++++++++++++++++++ .../dollar/interfaces/IUbiquityAMOPool.sol | 11 + 4 files changed, 254 insertions(+), 1 deletion(-) create mode 100644 packages/contracts/src/dollar/facets/UbiquityAMOPoolFacet.sol create mode 100644 packages/contracts/src/dollar/interfaces/IUbiquityAMOPool.sol diff --git a/cspell.json b/cspell.json index 265abdb52..175ede524 100644 --- a/cspell.json +++ b/cspell.json @@ -99,6 +99,7 @@ "Qmanager", "Rarible", "Reentrancy", + "recollateralize", "retdata", "returndata", "returndatacopy", @@ -119,6 +120,8 @@ "svgs", "testenv", "tippyjs", + "timelock", + "Timelock", "tlsv", "truetype", "turbotrace", diff --git a/packages/contracts/foundry.toml b/packages/contracts/foundry.toml index 8c5721de8..125231a48 100644 --- a/packages/contracts/foundry.toml +++ b/packages/contracts/foundry.toml @@ -5,7 +5,6 @@ out = 'out' libs = ['lib'] script = 'scripts' solc_version = '0.8.19' -evm_version = 'shanghai' extra_output = [ "abi", "evm.bytecode", diff --git a/packages/contracts/src/dollar/facets/UbiquityAMOPoolFacet.sol b/packages/contracts/src/dollar/facets/UbiquityAMOPoolFacet.sol new file mode 100644 index 000000000..b69501061 --- /dev/null +++ b/packages/contracts/src/dollar/facets/UbiquityAMOPoolFacet.sol @@ -0,0 +1,240 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.19; + +import {IUbiquityAMOPool} from "../../dollar/interfaces/IUbiquityAMOPool.sol"; +import {Modifiers} from "../libraries/LibAppStorage.sol"; + +/** + * @notice Ubiquity AMO Pool contract based on Frax Finance + * @notice Inspired from Frax Finance https://github.com/FraxFinance/frax-solidity + */ +contract UbiquityAMOPoolFacet is IUbiquityAMOPool { + function collateral_information( + address _collat_address + ) external view returns (CollateralInformation memory return_data) { + return LibUbiquityAMOPool.collateral_information(); + } + + function allCollaterals() external view returns (address[] memory) { + return LibUbiquityAMOPool.allCollaterals(); + } + + function getUADPrice() public view returns (uint256) { + return LibUbiquityAMOPool.getUADPrice(); + } + + function getGovTokenPrice() public view returns (uint256) { + return LibUbiquityAMOPool.getGovTokenPrice(); + } + + function getUADInCollateral( + uint256 _col_idx, + uint256 _uad_amount + ) public view returns (uint256) { + return LibUbiquityAMOPool.getUADInCollateral(); + } + + function freeCollatBalance(uint256 _col_idx) public view returns (uint256) { + return LibUbiquityAMOPool.getUADInCollateral(); + } + + function collatDollarBalance() external view returns (uint256) { + return LibUbiquityAMOPool.collateralDollarBalance(); + } + + function buybackAvailableCollateral() external view returns (uint256) { + return LibUbiquityAMOPool.buybackAvailableCollateral(); + } + + function recollateralizeColAvailableE18() external view returns (uint256) { + return LibUbiquityAMOPool.recollateralizeColAvailableE18(); + } + + function recollateralizeAvailableGovToken() public view returns (uint256) { + return LibUbiquityAMOPool.recollateralizeAvailableGovToken(); + } + + function curEpochHr() public view returns (uint256) { + return LibUbiquityAMOPool.curEpochHr(); + } + + function mintUad( + uint256 _col_idx, + uint256 _uad_amt, + uint256 _uad_out_min, + uint256 _max_collateral_in, + uint256 _max_gov_token_in, + bool _one_to_one_override + ) + external + returns ( + uint256 total_uad_mint, + uint256 collateral_needed, + uint256 gov_token_needed + ) + { + return + LibUbiquityAMOPool.mintUad( + _col_idx, + _uad_amt, + _uad_out_min, + _max_collateral_in, + _max_gov_token_in, + _one_to_one_override + ); + } + + function redeemUad( + uint256 _col_idx, + uint256 _uad_amount, + uint256 _gov_token_out_min, + uint256 _col_out_min + ) external returns (uint256 collateral_out, uint256 gov_token_out) { + return + LibUbiquityAMOPool.redeemUad( + _col_idx, + _uad_amount, + _gov_token_out_min, + _col_out_min + ); + } + + function collectRedemption( + uint256 _col_idx + ) external returns (uint256 gov_token_amount, uint256 collateral_amount) { + return LibUbiquityAMOPool.collectRedemption(_col_idx); + } + + function buyBackGovToken( + uint256 _col_idx, + uint256 _gov_token_amount, + uint256 _col_out_min + ) external returns (uint256 col_out) { + return + LibUbiquityAMOPool.buyBackGovToken( + _col_idx, + _gov_token_amount, + _col_out_min + ); + } + + function recollateralize( + uint256 _col_idx, + uint256 _collateral_amount, + uint256 _gov_token_out_min + ) external returns (uint256 gov_token_out) { + return + LibUbiquityAMOPool.recollateralize( + _col_idx, + _collateral_amount, + _gov_token_out_min + ); + } + + function amoMinterBorrow( + uint256 _collateral_amount + ) external onlyAMOMinters { + LibUbiquityAMOPool.amoMinterBorrow(_collateral_amount); + } + + /* ========== RESTRICTED FUNCTIONS, CUSTODIAN CAN CALL TOO ========== */ + + function toggleProtocol( + uint256 _col_idx, + uint8 _tog_idx + ) external onlyGovCustodian { + LibUbiquityAMOPool.toggleProtocol(_col_idx, _tog_idx); + } + + /* ========== RESTRICTED FUNCTIONS, GOVERNANCE ONLY ========== */ + + function addAMOMinter(address _amo_minter_addr) external onlyByOwnGov { + LibUbiquityAMOPool.addAMOMinter(_amo_minter_addr); + } + + function removeAMOMinter(address _amo_minter_addr) external onlyByOwnGov { + LibUbiquityAMOPool.removeAMOMinter(_amo_minter_addr); + } + + function setCollateralPrice( + uint256 _col_idx, + uint256 _new_price + ) external onlyByOwnGov { + LibUbiquityAMOPool.setCollateralPrice(_col_idx, _new_price); + } + + function toggleCollateral(uint256 _col_idx) external onlyByOwnGov { + LibUbiquityAMOPool.toggleCollateral(_col_idx); + } + + function setPoolCeiling( + uint256 _col_idx, + uint256 _new_ceiling + ) external onlyByOwnGov { + LibUbiquityAMOPool.setPoolCeiling(_col_idx, _new_ceiling); + } + + function setFees( + uint256 _col_idx, + uint256 _new_mint_fee, + uint256 _new_redeem_fee, + uint256 _new_buyback_fee, + uint256 _new_collateral_fee + ) external onlyByOwnGov { + LibUbiquityAMOPool.setFees( + _col_idx, + _new_mint_fee, + _new_redeem_fee, + _new_buyback_fee, + _new_collateral_fee + ); + } + + function setPoolParameters( + uint256 _new_bonus_rate, + uint256 _new_redemption_delay + ) external onlyByOwnGov { + LibUbiquityAMOPool.setPoolParameters( + _new_bonus_rate, + _new_redemption_delay + ); + } + + function setPriceThresholds( + uint256 _new_mint_price_threshold, + uint256 _new_redeem_price_threshold + ) external onlyByOwnGov { + LibUbiquityAMOPool.setPriceThresholds( + _new_mint_price_threshold, + _new_redeem_price_threshold + ); + } + + function setBbkRctPerHour( + uint256 _bbkMaxColE18OutPerHour, + uint256 _rctMaxFxsOutPerHour + ) external onlyByOwnGov { + LibUbiquityAMOPool.setBbkRctPerHour( + _bbkMaxColE18OutPerHour, + _rctMaxFxsOutPerHour + ); + } + + function setOracles( + address _uad_usd_chainlink_addr, + address _gov_token_usd_chainlink_addr + ) external onlyByOwnGov { + LibUbiquityAMOPool.setOracles( + _uad_usd_chainlink_addr, + _gov_token_usd_chainlink_addr + ); + } + + function setCustodian(address _new_custodian) external onlyByOwnGov { + LibUbiquityAMOPool.setCustodian(_new_custodian); + } + + function setTimelock(address _new_timelock) external onlyByOwnGov { + LibUbiquityAMOPool.setTimelock(_new_timelock); + } +} diff --git a/packages/contracts/src/dollar/interfaces/IUbiquityAMOPool.sol b/packages/contracts/src/dollar/interfaces/IUbiquityAMOPool.sol new file mode 100644 index 000000000..97bfa0b1a --- /dev/null +++ b/packages/contracts/src/dollar/interfaces/IUbiquityAMOPool.sol @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.19; + +// import "./IERC20Ubiquity.sol"; + +/** + * @notice Ubiquity Governance token interface + */ +interface IUbiquityAMOPool { + +} From 6db89264255aff7cbb4b89deaedfa194e4be0782 Mon Sep 17 00:00:00 2001 From: Doc Akan Date: Mon, 18 Sep 2023 20:50:58 +0100 Subject: [PATCH 2/5] feat: added amo minter --- .../dollar/facets/UbiquityAMOMinterFacet.sol | 127 ++++++++++++++++++ .../dollar/facets/UbiquityAMOPoolFacet.sol | 4 +- .../dollar/interfaces/IUbiquityAMOMinter.sol | 11 ++ .../dollar/libraries/LibUbiquityAMOMinter.sol | 11 ++ .../dollar/libraries/LibUbiquityAMOPool.sol | 11 ++ 5 files changed, 163 insertions(+), 1 deletion(-) create mode 100644 packages/contracts/src/dollar/facets/UbiquityAMOMinterFacet.sol create mode 100644 packages/contracts/src/dollar/interfaces/IUbiquityAMOMinter.sol create mode 100644 packages/contracts/src/dollar/libraries/LibUbiquityAMOMinter.sol create mode 100644 packages/contracts/src/dollar/libraries/LibUbiquityAMOPool.sol diff --git a/packages/contracts/src/dollar/facets/UbiquityAMOMinterFacet.sol b/packages/contracts/src/dollar/facets/UbiquityAMOMinterFacet.sol new file mode 100644 index 000000000..fd4fc3b13 --- /dev/null +++ b/packages/contracts/src/dollar/facets/UbiquityAMOMinterFacet.sol @@ -0,0 +1,127 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.19; + +import {Modifiers} from "../libraries/LibAppStorage.sol"; +import {LibUbiquityAMOMinter} from "../libraries/LibUbiquityAMOMinter.sol"; + +import {IUbiquityAMOMinter} from "../../dollar/interfaces/IUbiquityAMOMinter.sol"; + +/** + * @notice Ubiquity AMO Pool contract based on Frax Finance + * @notice Inspired from Frax Finance https://github.com/FraxFinance/frax-solidity + */ +contract UbiquityAMOMinterFacet is IUbiquityAMOMinter { + function collatDollarBalance() external view returns (uint256) { + LibUbiquityAMOMinter.collatDollarBalance(); + } + + function dollarBalances() + public + view + returns (uint256 _uAD_val_e18, uint256 _collateral_val_e18) + { + LibUbiquityAMOMinter.dollarBalances(_uAD_val_e18, _collateral_val_e18); + } + + function allAMOAddresses() external view returns (address[] memory) { + return LibUbiquityAMOMinter.allAMOAddresses; + } + + function allAMOsLength() external view returns (uint256) { + return LibUbiquityAMOMinter.allAMOsLength; + } + + function uADTrackedGlobal() external view returns (int256) { + return LibUbiquityAMOMinter.uADTrackedGlobal(); + } + + function uADTrackedAMO( + address _amo_address + ) external view returns (int256) { + return LibUbiquityAMOMinter.uADTrackedAMO(_amo_address); + } + + function syncDollarBalances() public { + LibUbiquityAMOMinter.syncDollarBalances(); + } + + function giveCollatToAMO( + address _destination_amo, + uint256 _collateral_amount + ) external onlyByOwnGov { + LibUbiquityAMOMinter.giveCollatToAMO; + } + + function receiveCollatFromAMO(uint256 usdc_amount) external { + LibUbiquityAMOMinter.receiveCollatFromAMO; + } + + function addAMO(address _amo_address, bool sync_too) external onlyByOwnGov { + LibUbiquityAMOMinter.addAMO; + } + + function removeAMO( + address _amo_address, + bool _sync_too + ) external onlyByOwnGov { + LibUbiquityAMOMinter.removeAMO; + } + + function setTimelock(address _new_timelock) external onlyByOwnGov { + LibUbiquityAMOMinter.setTimelock(_new_timelock); + } + + function setCustodian(address _custodian_address) external onlyByOwnGov { + LibUbiquityAMOMinter.setCustodian(_custodian_address); + } + + function setUadMintCap(uint256 _uAD_mint_cap) external onlyByOwnGov { + LibUbiquityAMOMinter.setUadMintCap(_uAD_mint_cap); + } + + function setuGovMintCap(uint256 _uGov_mint_cap) external onlyByOwnGov { + LibUbiquityAMOMinter.setuGovMintCap(_uGov_mint_cap); + } + + function setCollatBorrowCap( + uint256 _collat_borrow_cap + ) external onlyByOwnGov { + LibUbiquityAMOMinter.setCollatBorrowCap(_collat_borrow_cap); + } + + function setMinimumCollateralRatio(uint256 _min_cr) external onlyByOwnGov { + LibUbiquityAMOMinter.setMinimumCollateralRatio(_min_cr); + } + + function setAMOCorrectionOffsets( + address _amo_address, + int256 _uAD_e18_correction, + int256 _collat_e18_correction + ) external onlyByOwnGov { + LibUbiquityAMOMinter.setAMOCorrectionOffsets( + _amo_address, + _uAD_e18_correction, + _collat_e18_correction + ); + } + + function setUadPool(address _pool_address) external onlyByOwnGov { + LibUbiquityAMOMinter.setUadPool(_pool_address); + } + + function recoverERC20( + address _tokenAddress, + uint256 _tokenAmount + ) external onlyByOwnGov { + LibUbiquityAMOMinter.recoverERC20(_tokenAddress, _tokenAmount); + } + + // Generic proxy + function execute( + address _to, + uint256 _value, + bytes calldata _data + ) external onlyByOwnGov returns (bool, bytes memory) { + LibUbiquityAMOMinter.execute(_to, _value, _data); + } +} diff --git a/packages/contracts/src/dollar/facets/UbiquityAMOPoolFacet.sol b/packages/contracts/src/dollar/facets/UbiquityAMOPoolFacet.sol index b69501061..6a947df08 100644 --- a/packages/contracts/src/dollar/facets/UbiquityAMOPoolFacet.sol +++ b/packages/contracts/src/dollar/facets/UbiquityAMOPoolFacet.sol @@ -1,8 +1,10 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.19; -import {IUbiquityAMOPool} from "../../dollar/interfaces/IUbiquityAMOPool.sol"; import {Modifiers} from "../libraries/LibAppStorage.sol"; +import {LibUbiquityAMOPool} from "../libraries/LibUbiquityAMOPool.sol"; + +import {IUbiquityAMOPool} from "../../dollar/interfaces/IUbiquityAMOPool.sol"; /** * @notice Ubiquity AMO Pool contract based on Frax Finance diff --git a/packages/contracts/src/dollar/interfaces/IUbiquityAMOMinter.sol b/packages/contracts/src/dollar/interfaces/IUbiquityAMOMinter.sol new file mode 100644 index 000000000..592338d65 --- /dev/null +++ b/packages/contracts/src/dollar/interfaces/IUbiquityAMOMinter.sol @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.19; + +// import "./IERC20Ubiquity.sol"; + +/** + * @notice Ubiquity Governance token interface + */ +interface IUbiquityAMOMinter { + +} diff --git a/packages/contracts/src/dollar/libraries/LibUbiquityAMOMinter.sol b/packages/contracts/src/dollar/libraries/LibUbiquityAMOMinter.sol new file mode 100644 index 000000000..6fb863130 --- /dev/null +++ b/packages/contracts/src/dollar/libraries/LibUbiquityAMOMinter.sol @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.19; + +/** + * @notice Bonding curve library based on Bancor formula + * @notice Inspired from Bancor protocol https://github.com/bancorprotocol/contracts + * @notice Used on UbiquiStick NFT minting + */ +library LibUbiquityAMOMinter { + +} diff --git a/packages/contracts/src/dollar/libraries/LibUbiquityAMOPool.sol b/packages/contracts/src/dollar/libraries/LibUbiquityAMOPool.sol new file mode 100644 index 000000000..655b50dc4 --- /dev/null +++ b/packages/contracts/src/dollar/libraries/LibUbiquityAMOPool.sol @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.19; + +/** + * @notice Bonding curve library based on Bancor formula + * @notice Inspired from Bancor protocol https://github.com/bancorprotocol/contracts + * @notice Used on UbiquiStick NFT minting + */ +library LibUbiquityAMOPool { + +} From 30ec6d456c9307fd8b80586b8147035d17961644 Mon Sep 17 00:00:00 2001 From: Doc Akan Date: Tue, 19 Sep 2023 11:05:21 +0100 Subject: [PATCH 3/5] feat: added modifiers --- cspell.json | 3 + .../dollar/facets/UbiquityAMOMinterFacet.sol | 35 ++++---- .../dollar/facets/UbiquityAMOPoolFacet.sol | 42 +++++----- .../src/dollar/libraries/Constants.sol | 3 + .../src/dollar/libraries/LibAppStorage.sol | 11 +++ .../dollar/libraries/LibUbiquityAMOPool.sol | 81 +++++++++++++++++++ 6 files changed, 140 insertions(+), 35 deletions(-) diff --git a/cspell.json b/cspell.json index 175ede524..4c45eab22 100644 --- a/cspell.json +++ b/cspell.json @@ -29,6 +29,8 @@ "adoc", "alloc", "ALUSD", + "AMOPOOL", + "amopool", "Arrakis", "Avenir", "Bancor", @@ -99,6 +101,7 @@ "Qmanager", "Rarible", "Reentrancy", + "recollat", "recollateralize", "retdata", "returndata", diff --git a/packages/contracts/src/dollar/facets/UbiquityAMOMinterFacet.sol b/packages/contracts/src/dollar/facets/UbiquityAMOMinterFacet.sol index fd4fc3b13..a055ba211 100644 --- a/packages/contracts/src/dollar/facets/UbiquityAMOMinterFacet.sol +++ b/packages/contracts/src/dollar/facets/UbiquityAMOMinterFacet.sol @@ -10,7 +10,7 @@ import {IUbiquityAMOMinter} from "../../dollar/interfaces/IUbiquityAMOMinter.sol * @notice Ubiquity AMO Pool contract based on Frax Finance * @notice Inspired from Frax Finance https://github.com/FraxFinance/frax-solidity */ -contract UbiquityAMOMinterFacet is IUbiquityAMOMinter { +contract UbiquityAMOMinterFacet is Modifiers, IUbiquityAMOMinter { function collatDollarBalance() external view returns (uint256) { LibUbiquityAMOMinter.collatDollarBalance(); } @@ -48,7 +48,7 @@ contract UbiquityAMOMinterFacet is IUbiquityAMOMinter { function giveCollatToAMO( address _destination_amo, uint256 _collateral_amount - ) external onlyByOwnGov { + ) external onlyTokenManager { LibUbiquityAMOMinter.giveCollatToAMO; } @@ -56,40 +56,47 @@ contract UbiquityAMOMinterFacet is IUbiquityAMOMinter { LibUbiquityAMOMinter.receiveCollatFromAMO; } - function addAMO(address _amo_address, bool sync_too) external onlyByOwnGov { + function addAMO( + address _amo_address, + bool sync_too + ) external onlyTokenManager { LibUbiquityAMOMinter.addAMO; } function removeAMO( address _amo_address, bool _sync_too - ) external onlyByOwnGov { + ) external onlyTokenManager { LibUbiquityAMOMinter.removeAMO; } - function setTimelock(address _new_timelock) external onlyByOwnGov { + function setTimelock(address _new_timelock) external onlyTokenManager { LibUbiquityAMOMinter.setTimelock(_new_timelock); } - function setCustodian(address _custodian_address) external onlyByOwnGov { + function setCustodian( + address _custodian_address + ) external onlyTokenManager { LibUbiquityAMOMinter.setCustodian(_custodian_address); } - function setUadMintCap(uint256 _uAD_mint_cap) external onlyByOwnGov { + function setUadMintCap(uint256 _uAD_mint_cap) external onlyTokenManager { LibUbiquityAMOMinter.setUadMintCap(_uAD_mint_cap); } - function setuGovMintCap(uint256 _uGov_mint_cap) external onlyByOwnGov { + function setuGovMintCap(uint256 _uGov_mint_cap) external onlyTokenManager { LibUbiquityAMOMinter.setuGovMintCap(_uGov_mint_cap); } function setCollatBorrowCap( uint256 _collat_borrow_cap - ) external onlyByOwnGov { + ) external onlyTokenManager { LibUbiquityAMOMinter.setCollatBorrowCap(_collat_borrow_cap); } - function setMinimumCollateralRatio(uint256 _min_cr) external onlyByOwnGov { + function setMinimumCollateralRatio( + uint256 _min_cr + ) external onlyTokenManager { LibUbiquityAMOMinter.setMinimumCollateralRatio(_min_cr); } @@ -97,7 +104,7 @@ contract UbiquityAMOMinterFacet is IUbiquityAMOMinter { address _amo_address, int256 _uAD_e18_correction, int256 _collat_e18_correction - ) external onlyByOwnGov { + ) external onlyTokenManager { LibUbiquityAMOMinter.setAMOCorrectionOffsets( _amo_address, _uAD_e18_correction, @@ -105,14 +112,14 @@ contract UbiquityAMOMinterFacet is IUbiquityAMOMinter { ); } - function setUadPool(address _pool_address) external onlyByOwnGov { + function setUadPool(address _pool_address) external onlyTokenManager { LibUbiquityAMOMinter.setUadPool(_pool_address); } function recoverERC20( address _tokenAddress, uint256 _tokenAmount - ) external onlyByOwnGov { + ) external onlyTokenManager { LibUbiquityAMOMinter.recoverERC20(_tokenAddress, _tokenAmount); } @@ -121,7 +128,7 @@ contract UbiquityAMOMinterFacet is IUbiquityAMOMinter { address _to, uint256 _value, bytes calldata _data - ) external onlyByOwnGov returns (bool, bytes memory) { + ) external onlyTokenManager returns (bool, bytes memory) { LibUbiquityAMOMinter.execute(_to, _value, _data); } } diff --git a/packages/contracts/src/dollar/facets/UbiquityAMOPoolFacet.sol b/packages/contracts/src/dollar/facets/UbiquityAMOPoolFacet.sol index 6a947df08..700a4240f 100644 --- a/packages/contracts/src/dollar/facets/UbiquityAMOPoolFacet.sol +++ b/packages/contracts/src/dollar/facets/UbiquityAMOPoolFacet.sol @@ -10,12 +10,12 @@ import {IUbiquityAMOPool} from "../../dollar/interfaces/IUbiquityAMOPool.sol"; * @notice Ubiquity AMO Pool contract based on Frax Finance * @notice Inspired from Frax Finance https://github.com/FraxFinance/frax-solidity */ -contract UbiquityAMOPoolFacet is IUbiquityAMOPool { - function collateral_information( - address _collat_address - ) external view returns (CollateralInformation memory return_data) { - return LibUbiquityAMOPool.collateral_information(); - } +contract UbiquityAMOPoolFacet is Modifiers, IUbiquityAMOPool { + // function collateral_information( + // address _collateral_address + // ) external view returns (CollateralInformation memory return_data) { + // return LibUbiquityAMOPool.collateral_information(); + // } function allCollaterals() external view returns (address[] memory) { return LibUbiquityAMOPool.allCollaterals(); @@ -133,9 +133,7 @@ contract UbiquityAMOPoolFacet is IUbiquityAMOPool { ); } - function amoMinterBorrow( - uint256 _collateral_amount - ) external onlyAMOMinters { + function amoMinterBorrow(uint256 _collateral_amount) external onlyMinter { LibUbiquityAMOPool.amoMinterBorrow(_collateral_amount); } @@ -150,29 +148,31 @@ contract UbiquityAMOPoolFacet is IUbiquityAMOPool { /* ========== RESTRICTED FUNCTIONS, GOVERNANCE ONLY ========== */ - function addAMOMinter(address _amo_minter_addr) external onlyByOwnGov { + function addAMOMinter(address _amo_minter_addr) external onlyTokenManager { LibUbiquityAMOPool.addAMOMinter(_amo_minter_addr); } - function removeAMOMinter(address _amo_minter_addr) external onlyByOwnGov { + function removeAMOMinter( + address _amo_minter_addr + ) external onlyTokenManager { LibUbiquityAMOPool.removeAMOMinter(_amo_minter_addr); } function setCollateralPrice( uint256 _col_idx, uint256 _new_price - ) external onlyByOwnGov { + ) external onlyTokenManager { LibUbiquityAMOPool.setCollateralPrice(_col_idx, _new_price); } - function toggleCollateral(uint256 _col_idx) external onlyByOwnGov { + function toggleCollateral(uint256 _col_idx) external onlyTokenManager { LibUbiquityAMOPool.toggleCollateral(_col_idx); } function setPoolCeiling( uint256 _col_idx, uint256 _new_ceiling - ) external onlyByOwnGov { + ) external onlyTokenManager { LibUbiquityAMOPool.setPoolCeiling(_col_idx, _new_ceiling); } @@ -182,7 +182,7 @@ contract UbiquityAMOPoolFacet is IUbiquityAMOPool { uint256 _new_redeem_fee, uint256 _new_buyback_fee, uint256 _new_collateral_fee - ) external onlyByOwnGov { + ) external onlyTokenManager { LibUbiquityAMOPool.setFees( _col_idx, _new_mint_fee, @@ -195,7 +195,7 @@ contract UbiquityAMOPoolFacet is IUbiquityAMOPool { function setPoolParameters( uint256 _new_bonus_rate, uint256 _new_redemption_delay - ) external onlyByOwnGov { + ) external onlyTokenManager { LibUbiquityAMOPool.setPoolParameters( _new_bonus_rate, _new_redemption_delay @@ -205,7 +205,7 @@ contract UbiquityAMOPoolFacet is IUbiquityAMOPool { function setPriceThresholds( uint256 _new_mint_price_threshold, uint256 _new_redeem_price_threshold - ) external onlyByOwnGov { + ) external onlyTokenManager { LibUbiquityAMOPool.setPriceThresholds( _new_mint_price_threshold, _new_redeem_price_threshold @@ -215,7 +215,7 @@ contract UbiquityAMOPoolFacet is IUbiquityAMOPool { function setBbkRctPerHour( uint256 _bbkMaxColE18OutPerHour, uint256 _rctMaxFxsOutPerHour - ) external onlyByOwnGov { + ) external onlyTokenManager { LibUbiquityAMOPool.setBbkRctPerHour( _bbkMaxColE18OutPerHour, _rctMaxFxsOutPerHour @@ -225,18 +225,18 @@ contract UbiquityAMOPoolFacet is IUbiquityAMOPool { function setOracles( address _uad_usd_chainlink_addr, address _gov_token_usd_chainlink_addr - ) external onlyByOwnGov { + ) external onlyTokenManager { LibUbiquityAMOPool.setOracles( _uad_usd_chainlink_addr, _gov_token_usd_chainlink_addr ); } - function setCustodian(address _new_custodian) external onlyByOwnGov { + function setCustodian(address _new_custodian) external onlyTokenManager { LibUbiquityAMOPool.setCustodian(_new_custodian); } - function setTimelock(address _new_timelock) external onlyByOwnGov { + function setTimelock(address _new_timelock) external onlyTokenManager { LibUbiquityAMOPool.setTimelock(_new_timelock); } } diff --git a/packages/contracts/src/dollar/libraries/Constants.sol b/packages/contracts/src/dollar/libraries/Constants.sol index a2b323acb..f5a2cdfea 100644 --- a/packages/contracts/src/dollar/libraries/Constants.sol +++ b/packages/contracts/src/dollar/libraries/Constants.sol @@ -60,6 +60,9 @@ bytes32 constant CREDIT_NFT_MANAGER_ROLE = keccak256("CREDIT_NFT_MANAGER_ROLE"); /// @dev Role name for Staking manager bytes32 constant STAKING_MANAGER_ROLE = keccak256("STAKING_MANAGER_ROLE"); +/// @dev Role name for Staking manager +bytes32 constant GOV_CUSTODIAN_ROLE = keccak256("GOV_CUSTODIAN_ROLE"); + /// @dev Role name for inventive manager bytes32 constant INCENTIVE_MANAGER_ROLE = keccak256("INCENTIVE_MANAGER"); diff --git a/packages/contracts/src/dollar/libraries/LibAppStorage.sol b/packages/contracts/src/dollar/libraries/LibAppStorage.sol index 6bd153c67..54175a4e4 100644 --- a/packages/contracts/src/dollar/libraries/LibAppStorage.sol +++ b/packages/contracts/src/dollar/libraries/LibAppStorage.sol @@ -28,6 +28,8 @@ struct AppStorage { address ubiquiStickAddress; address bondingCurveAddress; address bancorFormulaAddress; + address ubiquityAmoPoolAddress; + address ubiquityAmoMinterAddress; address curveDollarIncentiveAddress; mapping(address => address) _excessDollarDistributors; // pausable @@ -168,6 +170,15 @@ contract Modifiers { _; } + /// @notice Checks that method is called by address with the `INCENTIVE_MANAGER_ROLE` role + modifier onlyGovCustodian() { + require( + LibAccessControl.hasRole(GOV_CUSTODIAN_ROLE, msg.sender), + "GovCustodian: not admin" + ); + _; + } + /// @notice Checks that method is called by address with the `CURVE_DOLLAR_MANAGER_ROLE` role modifier onlyDollarManager() { require( diff --git a/packages/contracts/src/dollar/libraries/LibUbiquityAMOPool.sol b/packages/contracts/src/dollar/libraries/LibUbiquityAMOPool.sol index 655b50dc4..3a5fc5e46 100644 --- a/packages/contracts/src/dollar/libraries/LibUbiquityAMOPool.sol +++ b/packages/contracts/src/dollar/libraries/LibUbiquityAMOPool.sol @@ -1,11 +1,92 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.19; +import {LibAppStorage} from "./LibAppStorage.sol"; +import {Modifiers} from "../libraries/LibAppStorage.sol"; + +// import {IBondingCurve} from "../../dollar/interfaces/IBondingCurve.sol"; + /** * @notice Bonding curve library based on Bancor formula * @notice Inspired from Bancor protocol https://github.com/bancorprotocol/contracts * @notice Used on UbiquiStick NFT minting */ library LibUbiquityAMOPool { + bytes32 constant AMOPOOL_CONTROL_STORAGE_SLOT = + bytes32(uint256(keccak256("ubiquity.contracts.amopool.storage")) - 1); + + event CollateralToggled(uint256 col_idx, bool new_state); + event PoolCeilingSet(uint256 col_idx, uint256 new_ceiling); + event FeesSet( + uint256 col_idx, + uint256 new_mint_fee, + uint256 new_redeem_fee, + uint256 new_buyback_fee, + uint256 new_recollat_fee + ); + event PoolParametersSet( + uint256 new_bonus_rate, + uint256 new_redemption_delay + ); + event PriceThresholdsSet( + uint256 new_bonus_rate, + uint256 new_redemption_delay + ); + event BbkRctPerHourSet( + uint256 bbkMaxColE18OutPerHour, + uint256 rctMaxFxsOutPerHour + ); + event AMOMinterAdded(address amo_minter_addr); + event AMOMinterRemoved(address amo_minter_addr); + event OraclesSet( + address frax_usd_chainlink_addr, + address fxs_usd_chainlink_addr + ); + event CustodianSet(address new_custodian); + event TimelockSet(address new_timelock); + event Toggled(uint256 col_idx, uint8 tog_idx); + event CollateralPriceSet(uint256 col_idx, uint256 new_price); + + struct AmoPoolData { + mapping(address => bool) enabled_collaterals; + } + + /** + * @notice Returns struct used as a storage for this library + * @return l Struct used as a storage + */ + function amoPoolStorage() internal pure returns (AmoPoolData storage l) { + bytes32 slot = AMOPOOL_CONTROL_STORAGE_SLOT; + assembly { + l.slot := slot + } + } + + // function collateral_information( + // address _collateral_address + // ) internal view returns (CollateralInformation memory return_data) { + // require(enabled_collaterals[collat_address], "Invalid collateral"); + + // // Get the index + // uint256 idx = collateralAddrToIdx[collat_address]; + // return_data = CollateralInformation( + // idx, // [0] + // collateral_symbols[idx], // [1] + // collat_address, // [2] + // enabled_collaterals[collat_address], // [3] + // missing_decimals[idx], // [4] + // collateral_prices[idx], // [5] + // pool_ceilings[idx], // [6] + // mintPaused[idx], // [7] + // redeemPaused[idx], // [8] + // recollateralizePaused[idx], // [9] + // buyBackPaused[idx], // [10] + // borrowingPaused[idx], // [11] + // minting_fee[idx], // [12] + // redemption_fee[idx], // [13] + // buyback_fee[idx], // [14] + // recollat_fee[idx] // [15] + // ); + // } } From c5cab4687f204a017a4ea11c8a2d205c7113875b Mon Sep 17 00:00:00 2001 From: Doc Akan Date: Tue, 19 Sep 2023 13:33:35 +0100 Subject: [PATCH 4/5] feat: implementing amominter lib --- cspell.json | 3 + .../dollar/facets/UbiquityAMOMinterFacet.sol | 6 +- .../contracts/src/dollar/interfaces/IAMO.sol | 11 +++ .../dollar/libraries/LibUbiquityAMOMinter.sol | 71 +++++++++++++++++++ .../dollar/libraries/LibUbiquityAMOPool.sol | 5 ++ 5 files changed, 93 insertions(+), 3 deletions(-) create mode 100644 packages/contracts/src/dollar/interfaces/IAMO.sol diff --git a/cspell.json b/cspell.json index 4c45eab22..05e9f6047 100644 --- a/cspell.json +++ b/cspell.json @@ -31,6 +31,8 @@ "ALUSD", "AMOPOOL", "amopool", + "AMOMINTER", + "amominter", "Arrakis", "Avenir", "Bancor", @@ -67,6 +69,7 @@ "Funcs", "Gelato", "habemus", + "IAMO", "iefix", "IERC", "Immer", diff --git a/packages/contracts/src/dollar/facets/UbiquityAMOMinterFacet.sol b/packages/contracts/src/dollar/facets/UbiquityAMOMinterFacet.sol index a055ba211..24f4cb221 100644 --- a/packages/contracts/src/dollar/facets/UbiquityAMOMinterFacet.sol +++ b/packages/contracts/src/dollar/facets/UbiquityAMOMinterFacet.sol @@ -20,15 +20,15 @@ contract UbiquityAMOMinterFacet is Modifiers, IUbiquityAMOMinter { view returns (uint256 _uAD_val_e18, uint256 _collateral_val_e18) { - LibUbiquityAMOMinter.dollarBalances(_uAD_val_e18, _collateral_val_e18); + LibUbiquityAMOMinter.dollarBalances(); } function allAMOAddresses() external view returns (address[] memory) { - return LibUbiquityAMOMinter.allAMOAddresses; + return LibUbiquityAMOMinter.allAMOAddresses(); } function allAMOsLength() external view returns (uint256) { - return LibUbiquityAMOMinter.allAMOsLength; + return LibUbiquityAMOMinter.allAMOsLength(); } function uADTrackedGlobal() external view returns (int256) { diff --git a/packages/contracts/src/dollar/interfaces/IAMO.sol b/packages/contracts/src/dollar/interfaces/IAMO.sol new file mode 100644 index 000000000..a8722e791 --- /dev/null +++ b/packages/contracts/src/dollar/interfaces/IAMO.sol @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.19; +pragma experimental ABIEncoderV2; + +interface IAMO { + function dollarBalances() + external + view + returns (uint256 frax_val_e18, uint256 collat_val_e18); +} diff --git a/packages/contracts/src/dollar/libraries/LibUbiquityAMOMinter.sol b/packages/contracts/src/dollar/libraries/LibUbiquityAMOMinter.sol index 6fb863130..754a6c9b8 100644 --- a/packages/contracts/src/dollar/libraries/LibUbiquityAMOMinter.sol +++ b/packages/contracts/src/dollar/libraries/LibUbiquityAMOMinter.sol @@ -1,11 +1,82 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.19; +import {LibAppStorage} from "./LibAppStorage.sol"; +import {Modifiers} from "../libraries/LibAppStorage.sol"; +import "../interfaces/IAMO.sol"; + /** * @notice Bonding curve library based on Bancor formula * @notice Inspired from Bancor protocol https://github.com/bancorprotocol/contracts * @notice Used on UbiquiStick NFT minting */ library LibUbiquityAMOMinter { + bytes32 constant AMOMINTER_CONTROL_STORAGE_SLOT = + bytes32(uint256(keccak256("ubiquity.contracts.amominter.storage")) - 1); + + struct AmoPoolData { + uint256 uadDollarBalanceStored; + uint256 collatDollarBalanceStored; + uint256 missing_decimals; + int256 uad_mint_sum; + int256 collat_borrowed_sum; + address[] amos_array; + mapping(address => int256[2]) correction_offsets_amos; + mapping(address => int256) uad_mint_balances; + mapping(address => int256) collat_borrowed_balances; + } + + /** + * @notice Returns struct used as a storage for this library + * @return l Struct used as a storage + */ + function amoMinterStorage() internal pure returns (AmoPoolData storage l) { + bytes32 slot = AMOMINTER_CONTROL_STORAGE_SLOT; + assembly { + l.slot := slot + } + } + + function collatDollarBalance() external view returns (uint256) { + (, uint256 collat_val_e18) = dollarBalances(); + return collat_val_e18; + } + + function dollarBalances() + internal + view + returns (uint256 uad_val_e18, uint256 collat_val_e18) + { + uad_val_e18 = amoMinterStorage().uadDollarBalanceStored; + collat_val_e18 = amoMinterStorage().collatDollarBalanceStored; + } + + function allAMOAddresses() internal view returns (address[] memory) { + return amoMinterStorage().amos_array; + } + + function allAMOsLength() internal view returns (uint256) { + return amoMinterStorage().amos_array.length; + } + + function uADTrackedGlobal() internal view returns (int256) { + return + int256(amoMinterStorage().uadDollarBalanceStored) - + amoMinterStorage().uad_mint_sum - + (amoMinterStorage().collat_borrowed_sum * + int256(10 ** amoMinterStorage().missing_decimals)); + } + function uADTrackedAMO( + address _amo_address + ) external view returns (int256) { + (uint256 uad_val_e18, ) = IAMO(_amo_address).dollarBalances(); + int256 uad_val_e18_corrected = int256(uad_val_e18) + + amoMinterStorage().correction_offsets_amos[_amo_address][0]; + return + uad_val_e18_corrected - + amoMinterStorage().uad_mint_balances[_amo_address] - + ((amoMinterStorage().collat_borrowed_balances[_amo_address]) * + int256(10 ** amoMinterStorage().missing_decimals)); + } } diff --git a/packages/contracts/src/dollar/libraries/LibUbiquityAMOPool.sol b/packages/contracts/src/dollar/libraries/LibUbiquityAMOPool.sol index 3a5fc5e46..56db04252 100644 --- a/packages/contracts/src/dollar/libraries/LibUbiquityAMOPool.sol +++ b/packages/contracts/src/dollar/libraries/LibUbiquityAMOPool.sol @@ -48,6 +48,7 @@ library LibUbiquityAMOPool { event CollateralPriceSet(uint256 col_idx, uint256 new_price); struct AmoPoolData { + address[] collateral_addresses; mapping(address => bool) enabled_collaterals; } @@ -89,4 +90,8 @@ library LibUbiquityAMOPool { // recollat_fee[idx] // [15] // ); // } + + function allCollaterals() internal view returns (address[] memory) { + return amoPoolStorage().collateral_addresses; + } } From 125664bab08c27de50f4b2836c30f580629aabfb Mon Sep 17 00:00:00 2001 From: Doc Akan Date: Thu, 28 Sep 2023 13:14:12 +0100 Subject: [PATCH 5/5] feat: modifying libs --- .../dollar/libraries/LibUbiquityAMOMinter.sol | 31 ++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/packages/contracts/src/dollar/libraries/LibUbiquityAMOMinter.sol b/packages/contracts/src/dollar/libraries/LibUbiquityAMOMinter.sol index 754a6c9b8..d8e32afd4 100644 --- a/packages/contracts/src/dollar/libraries/LibUbiquityAMOMinter.sol +++ b/packages/contracts/src/dollar/libraries/LibUbiquityAMOMinter.sol @@ -69,7 +69,7 @@ library LibUbiquityAMOMinter { function uADTrackedAMO( address _amo_address - ) external view returns (int256) { + ) internal view returns (int256) { (uint256 uad_val_e18, ) = IAMO(_amo_address).dollarBalances(); int256 uad_val_e18_corrected = int256(uad_val_e18) + amoMinterStorage().correction_offsets_amos[_amo_address][0]; @@ -79,4 +79,33 @@ library LibUbiquityAMOMinter { ((amoMinterStorage().collat_borrowed_balances[_amo_address]) * int256(10 ** amoMinterStorage().missing_decimals)); } + + function syncDollarBalances() internal { + uint256 total_uad_value_d18 = 0; + uint256 total_collateral_value_d18 = 0; + for (uint i = 0; i < amoMinterStorage().amos_array.length; i++) { + // Exclude null addresses + address amo_address = amoMinterStorage().amos_array[i]; + if (amo_address != address(0)) { + (uint256 uad_val_e18, uint256 collat_val_e18) = IAMO( + amo_address + ).dollarBalances(); + total_uad_value_d18 += uint256( + int256(uad_val_e18) + + amoMinterStorage().correction_offsets_amos[amo_address][ + 0 + ] + ); + total_collateral_value_d18 += uint256( + int256(collat_val_e18) + + amoMinterStorage().correction_offsets_amos[amo_address][ + 1 + ] + ); + } + } + amoMinterStorage().uadDollarBalanceStored = total_uad_value_d18; + amoMinterStorage() + .collatDollarBalanceStored = total_collateral_value_d18; + } }