diff --git a/protocol/synthetix/contracts/interfaces/IPoolModule.sol b/protocol/synthetix/contracts/interfaces/IPoolModule.sol index 7046f44ece..3a4636468f 100644 --- a/protocol/synthetix/contracts/interfaces/IPoolModule.sol +++ b/protocol/synthetix/contracts/interfaces/IPoolModule.sol @@ -87,6 +87,13 @@ interface IPoolModule { */ event SetMinLiquidityRatio(uint256 minLiquidityRatio); + /** + * @notice Allows collaterals accepeted by the system to be accepeted by the pool by default + * @param poolId The id of the pool. + * @param disabled Shows if new collateral's will be dsiabled by default for the pool + */ + event PoolCollateralDisabledByDefaultSet(uint128 poolId, bool disabled); + /** * @notice Creates a pool with the requested pool id. * @param requestedPoolId The requested id for the new pool. Reverts if the id is not available. @@ -118,6 +125,13 @@ interface IPoolModule { PoolCollateralConfiguration.Data memory newConfig ) external; + /** + * @notice Allows collaterals accepeted by the system to be accepeted by the pool by default + * @param poolId The id of the pool. + * @param disabled If set to true new collaterals will be disabled for the pool. + */ + function setPoolCollateralDisabledByDefault(uint128 poolId, bool disabled) external; + /** * @notice Retrieves the MarketConfiguration of the specified pool. * @param poolId The id of the pool whose configuration is being queried. @@ -186,16 +200,6 @@ interface IPoolModule { */ function setMinLiquidityRatio(uint256 minLiquidityRatio) external; - /** - @notice Shows if a given collateral type is enabled for deposits and delegation in a given pool. - * @param poolId The id of the pool for to check the collateral for. - * @param collateral The address of the collateral. - */ - function isDelegationEnabledByPool( - uint128 poolId, - address collateral - ) external view returns (bool enabled); - /** @notice returns a pool minimum issuance ratio * @param poolId The id of the pool for to check the collateral for. diff --git a/protocol/synthetix/contracts/modules/core/PoolModule.sol b/protocol/synthetix/contracts/modules/core/PoolModule.sol index f2066b75a4..1b4cb7bc3a 100644 --- a/protocol/synthetix/contracts/modules/core/PoolModule.sol +++ b/protocol/synthetix/contracts/modules/core/PoolModule.sol @@ -197,6 +197,18 @@ contract PoolModule is IPoolModule { emit PoolConfigurationSet(poolId, newMarketConfigurations, msg.sender); } + /** + * @inheritdoc IPoolModule + */ + function setPoolCollateralDisabledByDefault(uint128 poolId, bool disabled) external override { + Pool.Data storage pool = Pool.loadExisting(poolId); + Pool.onlyPoolOwner(poolId, msg.sender); + + pool.collateralDisabledByDefault = disabled; + + emit PoolCollateralDisabledByDefaultSet(poolId, disabled); + } + /** * @inheritdoc IPoolModule */ @@ -228,17 +240,6 @@ contract PoolModule is IPoolModule { emit PoolNameUpdated(poolId, name, msg.sender); } - /** - * @inheritdoc IPoolModule - */ - function isDelegationEnabledByPool( - uint128 poolId, - address collateral - ) external view override returns (bool) { - return - !Pool.loadExisting(poolId).collateralConfigurations[collateral].collateralTypeDisabled; - } - /** * @inheritdoc IPoolModule */ diff --git a/protocol/synthetix/contracts/modules/core/VaultModule.sol b/protocol/synthetix/contracts/modules/core/VaultModule.sol index 82e7a34f1d..3226f97805 100644 --- a/protocol/synthetix/contracts/modules/core/VaultModule.sol +++ b/protocol/synthetix/contracts/modules/core/VaultModule.sol @@ -79,9 +79,6 @@ contract VaultModule is IVaultModule { // Check if the collateral is enabled here because we still want to allow reducing delegation for disabled collaterals. CollateralConfiguration.collateralEnabled(collateralType); - // Check if delegation is enabled for the pool - Pool.load(poolId).checkDelegationEnabled(collateralType); - Account.requireSufficientCollateral( accountId, collateralType, diff --git a/protocol/synthetix/contracts/storage/Pool.sol b/protocol/synthetix/contracts/storage/Pool.sol index e4ca31fe27..04b3bfaa93 100644 --- a/protocol/synthetix/contracts/storage/Pool.sol +++ b/protocol/synthetix/contracts/storage/Pool.sol @@ -60,11 +60,6 @@ library Pool { uint256 maxCollateral ); - /** - * @notice Thrown when attempting delegate a pool disabled collateral - */ - error PoolCollateralIsDisabled(address collateral, uint128 poolId); - bytes32 private constant _CONFIG_SET_MARKET_MIN_DELEGATE_MAX = "setMarketMinDelegateTime_max"; struct Data { @@ -131,6 +126,14 @@ library Pool { uint64 __reserved2; uint64 __reserved3; mapping(address => PoolCollateralConfiguration.Data) collateralConfigurations; + /** + * @dev A switch to make the pool opt-in for new collateral + * + * By default it's set to false, which means any new collateral accepeted by the system will be accpeted by the pool. + * + * If the pool owner sets this value to true, then new collaterals will be disabled for the pool unless a maxDeposit is set for a that collateral. + */ + bool collateralDisabledByDefault; } /** @@ -534,8 +537,9 @@ library Pool { uint256 maxDeposit = self.collateralConfigurations[collateralType].maxDepositD18; if ( - maxDeposit > 0 && - self.vaults[collateralType].currentCollateral() + collateralAmountD18 > maxDeposit + (self.collateralDisabledByDefault && maxDeposit == 0) || + (maxDeposit > 0 && + self.vaults[collateralType].currentCollateral() + collateralAmountD18 > maxDeposit) ) { revert PoolCollateralLimitExceeded( self.id, @@ -545,14 +549,4 @@ library Pool { ); } } - - /** - * @notice Shows if a given collateral type is enabled for deposits and delegation in given pool. - * @param collateralType The address of the collateral. - */ - function checkDelegationEnabled(Data storage self, address collateralType) internal view { - if (self.collateralConfigurations[collateralType].collateralTypeDisabled) { - revert PoolCollateralIsDisabled(collateralType, self.id); - } - } } diff --git a/protocol/synthetix/contracts/storage/PoolCollateralConfiguration.sol b/protocol/synthetix/contracts/storage/PoolCollateralConfiguration.sol index 4b8457b786..89b5e17203 100644 --- a/protocol/synthetix/contracts/storage/PoolCollateralConfiguration.sol +++ b/protocol/synthetix/contracts/storage/PoolCollateralConfiguration.sol @@ -7,7 +7,6 @@ library PoolCollateralConfiguration { struct Data { uint256 maxDepositD18; - bool collateralTypeDisabled; uint256 issuanceRatioD18; } } diff --git a/protocol/synthetix/test/integration/bootstrap.ts b/protocol/synthetix/test/integration/bootstrap.ts index f8e71712a9..a3f33dee7b 100644 --- a/protocol/synthetix/test/integration/bootstrap.ts +++ b/protocol/synthetix/test/integration/bootstrap.ts @@ -113,7 +113,6 @@ export function bootstrapWithMockMarketAndPool() { .Core.connect(owner) .setPoolCollateralConfiguration(r.poolId, r.collateralAddress(), { maxDepositD18: bn(1000000000), - collateralTypeDisabled: false, issuanceRatioD18: bn(1), }); }); diff --git a/protocol/synthetix/test/integration/modules/core/IssueUSDModule.test.ts b/protocol/synthetix/test/integration/modules/core/IssueUSDModule.test.ts index 6e0f12da87..cbd51c7dac 100644 --- a/protocol/synthetix/test/integration/modules/core/IssueUSDModule.test.ts +++ b/protocol/synthetix/test/integration/modules/core/IssueUSDModule.test.ts @@ -467,7 +467,6 @@ describe('IssueUSDModule', function () { await systems() .Core.connect(owner) .setPoolCollateralConfiguration(poolId, collateralAddress(), { - collateralTypeDisabled: false, maxDepositD18: bn(10), issuanceRatioD18: bn(6), }); diff --git a/protocol/synthetix/test/integration/modules/core/PoolConfigurationModule/PoolConfigurationModule.test.ts b/protocol/synthetix/test/integration/modules/core/PoolConfigurationModule/PoolConfigurationModule.test.ts index 2c6e8ef3f9..7f551a77e5 100644 --- a/protocol/synthetix/test/integration/modules/core/PoolConfigurationModule/PoolConfigurationModule.test.ts +++ b/protocol/synthetix/test/integration/modules/core/PoolConfigurationModule/PoolConfigurationModule.test.ts @@ -9,7 +9,7 @@ import { bootstrap } from '../../../bootstrap'; describe('PoolConfigurationModule', function () { const { signers, systems } = bootstrap(); - let owner: Ethers.Signer, user1: Ethers.Signer; + let owner: Ethers.Signer, user1: Ethers.Signer, user2: Ethers.Signer; let receipt: Ethers.providers.TransactionReceipt; @@ -23,7 +23,7 @@ describe('PoolConfigurationModule', function () { describe('PoolConfigurationModule', function () { before('identify signers', async () => { - [owner, user1] = signers(); + [owner, user1, user2] = signers(); }); describe('when some pools are created', function () { @@ -183,6 +183,25 @@ describe('PoolConfigurationModule', function () { }); }); }); + + describe('when the owner tries to disable/enable new collaterals by default', () => { + it('setPoolCollateralDisabledByDefault is restricted to the pool owner', async () => { + await assertRevert( + systems().Core.connect(user2).setPoolCollateralDisabledByDefault(1, true), + `Unauthorized("${await user2.getAddress()}")`, + systems().Core + ); + }); + + it('pool owner disables new collaterals by default', async () => { + const tx = await systems() + .Core.connect(user1) + .setPoolCollateralDisabledByDefault(1, true); + + receipt = await tx.wait(); + await assertEvent(receipt, 'PoolCollateralDisabledByDefaultSet(1, true)', systems().Core); + }); + }); }); }); }); diff --git a/protocol/synthetix/test/integration/modules/core/PoolModuleFundAdmin.test.ts b/protocol/synthetix/test/integration/modules/core/PoolModuleFundAdmin.test.ts index 221d20c60e..0ab35181cd 100644 --- a/protocol/synthetix/test/integration/modules/core/PoolModuleFundAdmin.test.ts +++ b/protocol/synthetix/test/integration/modules/core/PoolModuleFundAdmin.test.ts @@ -714,7 +714,6 @@ describe('PoolModule Admin', function () { .Core.connect(user2) .setPoolCollateralConfiguration(thirdPoolId, collateralAddress(), { maxDepositD18: bn(10), - collateralTypeDisabled: false, issuanceRatioD18: bn(0), }), `Unauthorized("${await user2.getAddress()}")`, @@ -722,29 +721,14 @@ describe('PoolModule Admin', function () { ); }); - it('collateral is enabled by default for the pool', async () => { - await assert.equal( - await systems().Core.isDelegationEnabledByPool(thirdPoolId, collateralAddress()), - true - ); - }); - it('disable the collateral by pool owner', async () => { await systems() .Core.connect(user1) .setPoolCollateralConfiguration(thirdPoolId, collateralAddress(), { maxDepositD18: bn(10), - collateralTypeDisabled: true, issuanceRatioD18: bn(2), }); }); - - it('collateral is disabled for the pool', async () => { - await assert.equal( - await systems().Core.isDelegationEnabledByPool(thirdPoolId, collateralAddress()), - false - ); - }); }); describe('set pool collateral issuance ratio', async () => { @@ -773,7 +757,6 @@ describe('PoolModule Admin', function () { .Core.connect(user2) .setPoolCollateralConfiguration(thirdPoolId, collateralAddress(), { maxDepositD18: bn(10), - collateralTypeDisabled: false, issuanceRatioD18: bn(2), }), `Unauthorized("${await user2.getAddress()}")`, @@ -793,7 +776,6 @@ describe('PoolModule Admin', function () { .Core.connect(user1) .setPoolCollateralConfiguration(thirdPoolId, collateralAddress(), { maxDepositD18: bn(10), - collateralTypeDisabled: false, issuanceRatioD18: bn(2), }); diff --git a/protocol/synthetix/test/integration/modules/core/VaultModule.test.ts b/protocol/synthetix/test/integration/modules/core/VaultModule.test.ts index 1bd9b3159f..cfdef2c21a 100644 --- a/protocol/synthetix/test/integration/modules/core/VaultModule.test.ts +++ b/protocol/synthetix/test/integration/modules/core/VaultModule.test.ts @@ -340,7 +340,6 @@ describe('VaultModule', function () { .Core.connect(user1) .setPoolCollateralConfiguration(fakeVaultId, collateralAddress(), { maxDepositD18: bn(10), - collateralTypeDisabled: true, issuanceRatioD18: bn(0), }); }); @@ -357,7 +356,9 @@ describe('VaultModule', function () { depositAmount.div(50), ethers.utils.parseEther('1') ), - `PoolCollateralIsDisabled("${collateralAddress()}", "${fakeVaultId}")`, + `PoolCollateralLimitExceeded("${fakeVaultId}", "${collateralAddress()}", "${depositAmount + .div(50) + .toString()}", "${bn(10).toString()}")`, systems().Core ); }); @@ -367,7 +368,6 @@ describe('VaultModule', function () { .Core.connect(user1) .setPoolCollateralConfiguration(fakeVaultId, collateralAddress(), { maxDepositD18: bn(1000000), - collateralTypeDisabled: false, issuanceRatioD18: bn(0), }); }); @@ -391,7 +391,6 @@ describe('VaultModule', function () { .Core.connect(owner) .setPoolCollateralConfiguration(poolId, collateralAddress(), { maxDepositD18: depositAmount.div(2), - collateralTypeDisabled: false, issuanceRatioD18: bn(0), }); }); @@ -454,7 +453,6 @@ describe('VaultModule', function () { .Core.connect(owner) .setPoolCollateralConfiguration(poolId, collateralAddress(), { maxDepositD18: depositAmount.mul(10), - collateralTypeDisabled: false, issuanceRatioD18: bn(0), }); });