From 96b8943f099b4a2f589d122f42946f5714a5aa70 Mon Sep 17 00:00:00 2001 From: Peiman Date: Thu, 13 Jul 2023 00:50:34 +0330 Subject: [PATCH 01/63] feat: SIP-326, additional pool configuration --- .../contracts/interfaces/IPoolModule.sol | 66 +++++++++++ .../contracts/modules/core/IssueUSDModule.sol | 4 +- .../contracts/modules/core/PoolModule.sol | 60 ++++++++++ .../contracts/modules/core/VaultModule.sol | 10 +- .../storage/CollateralConfiguration.sol | 12 +- protocol/synthetix/contracts/storage/Pool.sol | 17 +++ protocol/synthetix/storage.dump.sol | 2 + .../modules/core/IssueUSDModule.test.ts | 26 ++++- .../modules/core/PoolModuleFundAdmin.test.ts | 103 +++++++++++++++++- .../modules/core/VaultModule.test.ts | 61 ++++++++++- .../storage/CollateralConfiguration.test.ts | 19 +++- 11 files changed, 366 insertions(+), 14 deletions(-) diff --git a/protocol/synthetix/contracts/interfaces/IPoolModule.sol b/protocol/synthetix/contracts/interfaces/IPoolModule.sol index bda29dccfd..3b07d1273c 100644 --- a/protocol/synthetix/contracts/interfaces/IPoolModule.sol +++ b/protocol/synthetix/contracts/interfaces/IPoolModule.sol @@ -80,6 +80,26 @@ interface IPoolModule { */ event SetMinLiquidityRatio(uint256 minLiquidityRatio); + /** + * @notice Gets fired when pool collateral is enabled. + * @param poolId The id of the pool for which the collateral is being enabled. + * @param collateral The address of the collateral. + * @param sender The address that triggered the action. + */ + event PoolCollateralEnabled(uint128 indexed poolId, address collateral, address indexed sender); + + /** + * @notice Gets fired when pool collateral is disabled. + * @param poolId The id of the pool for which the collateral is being disabled. + * @param collateral The address of the collateral. + * @param sender The address that triggered the action. + */ + event PoolCollateralDisabled( + uint128 indexed poolId, + address collateral, + address indexed sender + ); + /** * @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. @@ -167,6 +187,52 @@ interface IPoolModule { */ function setMinLiquidityRatio(uint256 minLiquidityRatio) external; + /** + * @notice Gets fired when a pool collateral is disabled for a pool. + * @param poolId The id of the pool for which the collateral is being disabled. + * @param collateral The address of the collateral. + */ + function disablePoolCollateralDelegation(uint128 poolId, address collateral) external; + + /** + * @notice Gets fired when a collateral is enabled for a pool. + * @param poolId The id of the pool for which the collateral is being enabled. + * @param collateral The address of the collateral. + */ + function enablePoolCollateralDelegation(uint128 poolId, address collateral) 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 sets a pool minimum issuance ratio + * @param poolId The id of the pool for to check the collateral for. + * @param collateral The address of the collateral. + * @param issuanceRatioD18 The minimum issuance ratio denominated with 18 decimal places + */ + function setPoolCollateralIssuanceRatioD18( + uint128 poolId, + address collateral, + uint256 issuanceRatioD18 + ) external; + + /** + @notice returns a pool minimum issuance ratio + * @param poolId The id of the pool for to check the collateral for. + * @param collateral The address of the collateral. + */ + function getPoolCollateralIssuanceRatioD18( + uint128 poolId, + address collateral + ) external returns (uint256 issuanceRatioD18); + /** * @notice Retrieves the system-wide minimum liquidity ratio. * @return minRatioD18 The current system-wide minimum liquidity ratio, denominated with 18 decimals of precision. (100% is represented by 1 followed by 18 zeros.) diff --git a/protocol/synthetix/contracts/modules/core/IssueUSDModule.sol b/protocol/synthetix/contracts/modules/core/IssueUSDModule.sol index f95f6955af..5c8aedb45b 100644 --- a/protocol/synthetix/contracts/modules/core/IssueUSDModule.sol +++ b/protocol/synthetix/contracts/modules/core/IssueUSDModule.sol @@ -84,9 +84,11 @@ contract IssueUSDModule is IIssueUSDModule { // If the resulting debt of the account is greater than zero, ensure that the resulting c-ratio is sufficient (, uint256 collateralValue) = pool.currentAccountCollateral(collateralType, accountId); if (newDebt > 0) { + uint256 minIssuanceRatioD18 = pool.issuanceRatioD18[collateralType]; CollateralConfiguration.load(collateralType).verifyIssuanceRatio( newDebt.toUint(), - collateralValue + collateralValue, + minIssuanceRatioD18 ); } diff --git a/protocol/synthetix/contracts/modules/core/PoolModule.sol b/protocol/synthetix/contracts/modules/core/PoolModule.sol index 93bed43105..59c3b46eb6 100644 --- a/protocol/synthetix/contracts/modules/core/PoolModule.sol +++ b/protocol/synthetix/contracts/modules/core/PoolModule.sol @@ -228,6 +228,66 @@ contract PoolModule is IPoolModule { emit PoolNameUpdated(poolId, name, msg.sender); } + /** + * @inheritdoc IPoolModule + */ + function enablePoolCollateralDelegation(uint128 poolId, address collateral) external override { + Pool.Data storage pool = Pool.loadExisting(poolId); + Pool.onlyPoolOwner(poolId, msg.sender); + + pool.disabledCollaterals[collateral] = false; + + emit PoolCollateralEnabled(poolId, collateral, msg.sender); + } + + /** + * @inheritdoc IPoolModule + */ + function disablePoolCollateralDelegation(uint128 poolId, address collateral) external override { + Pool.Data storage pool = Pool.loadExisting(poolId); + Pool.onlyPoolOwner(poolId, msg.sender); + + pool.disabledCollaterals[collateral] = true; + + emit PoolCollateralDisabled(poolId, collateral, msg.sender); + } + + /** + * @inheritdoc IPoolModule + */ + function isDelegationEnabledByPool( + uint128 poolId, + address collateral + ) external view override returns (bool) { + return !Pool.load(poolId).disabledCollaterals[collateral]; + } + + /** + * @inheritdoc IPoolModule + */ + function setPoolCollateralIssuanceRatioD18( + uint128 poolId, + address collateral, + uint256 issuanceRatioD18 + ) external override { + Pool.Data storage pool = Pool.loadExisting(poolId); + Pool.onlyPoolOwner(poolId, msg.sender); + + pool.issuanceRatioD18[collateral] = issuanceRatioD18; + + emit PoolCollateralDisabled(poolId, collateral, msg.sender); + } + + /** + * @inheritdoc IPoolModule + */ + function getPoolCollateralIssuanceRatioD18( + uint128 poolId, + address collateral + ) external view override returns (uint256) { + return Pool.loadExisting(poolId).issuanceRatioD18[collateral]; + } + /** * @inheritdoc IPoolModule */ diff --git a/protocol/synthetix/contracts/modules/core/VaultModule.sol b/protocol/synthetix/contracts/modules/core/VaultModule.sol index defd791dfd..4045db1586 100644 --- a/protocol/synthetix/contracts/modules/core/VaultModule.sol +++ b/protocol/synthetix/contracts/modules/core/VaultModule.sol @@ -79,6 +79,9 @@ 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, @@ -116,11 +119,16 @@ contract VaultModule is IVaultModule { if (newCollateralAmountD18 < currentCollateralAmount) { int256 debt = vault.currentEpoch().consolidatedDebtAmountsD18[accountId]; + uint256 minIssuanceRatioD18 = Pool.loadExisting(poolId).issuanceRatioD18[ + collateralType + ]; + // Minimum collateralization ratios are configured in the system per collateral type.abi // Ensure that the account's updated position satisfies this requirement. CollateralConfiguration.load(collateralType).verifyIssuanceRatio( debt < 0 ? 0 : debt.toUint(), - newCollateralAmountD18.mulDecimal(collateralPrice) + newCollateralAmountD18.mulDecimal(collateralPrice), + minIssuanceRatioD18 ); // Accounts cannot reduce collateral if any of the pool's diff --git a/protocol/synthetix/contracts/storage/CollateralConfiguration.sol b/protocol/synthetix/contracts/storage/CollateralConfiguration.sol index b504829c86..8a96625e39 100644 --- a/protocol/synthetix/contracts/storage/CollateralConfiguration.sol +++ b/protocol/synthetix/contracts/storage/CollateralConfiguration.sol @@ -205,18 +205,22 @@ library CollateralConfiguration { function verifyIssuanceRatio( Data storage self, uint256 debtD18, - uint256 collateralValueD18 + uint256 collateralValueD18, + uint256 minIssuanceRatioD18 ) internal view { + uint256 issuanceRatioD18 = self.issuanceRatioD18 > minIssuanceRatioD18 + ? self.issuanceRatioD18 + : minIssuanceRatioD18; + if ( debtD18 != 0 && - (collateralValueD18 == 0 || - collateralValueD18.divDecimal(debtD18) < self.issuanceRatioD18) + (collateralValueD18 == 0 || collateralValueD18.divDecimal(debtD18) < issuanceRatioD18) ) { revert InsufficientCollateralRatio( collateralValueD18, debtD18, collateralValueD18.divDecimal(debtD18), - self.issuanceRatioD18 + issuanceRatioD18 ); } } diff --git a/protocol/synthetix/contracts/storage/Pool.sol b/protocol/synthetix/contracts/storage/Pool.sol index 565d568ab8..efb1233a10 100644 --- a/protocol/synthetix/contracts/storage/Pool.sol +++ b/protocol/synthetix/contracts/storage/Pool.sol @@ -48,6 +48,11 @@ library Pool { */ error MinDelegationTimeoutPending(uint128 poolId, uint32 timeRemaining); + /** + * @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 { @@ -113,6 +118,8 @@ library Pool { uint64 __reserved1; uint64 __reserved2; uint64 __reserved3; + mapping(address => bool) disabledCollaterals; + mapping(address => uint256) issuanceRatioD18; } /** @@ -507,4 +514,14 @@ library Pool { ); } } + + /** + * @notice Shows if a given collateral type is enabled for deposits and delegation in given pool. + * @param collateral The address of the collateral. + */ + function checkDelegationEnabled(Data storage self, address collateral) internal view { + if (self.disabledCollaterals[collateral]) { + revert PoolCollateralIsDisabled(collateral, self.id); + } + } } diff --git a/protocol/synthetix/storage.dump.sol b/protocol/synthetix/storage.dump.sol index da90361cdf..0ed4e7e401 100644 --- a/protocol/synthetix/storage.dump.sol +++ b/protocol/synthetix/storage.dump.sol @@ -544,6 +544,8 @@ library Pool { uint64 __reserved1; uint64 __reserved2; uint64 __reserved3; + mapping(address => bool) disabledCollaterals; + mapping(address => uint256) IssuanceRatio; } function load(uint128 id) internal pure returns (Data storage pool) { bytes32 s = keccak256(abi.encode("io.synthetix.synthetix.Pool", id)); diff --git a/protocol/synthetix/test/integration/modules/core/IssueUSDModule.test.ts b/protocol/synthetix/test/integration/modules/core/IssueUSDModule.test.ts index 96c0b4d951..7b20b2ceec 100644 --- a/protocol/synthetix/test/integration/modules/core/IssueUSDModule.test.ts +++ b/protocol/synthetix/test/integration/modules/core/IssueUSDModule.test.ts @@ -4,7 +4,7 @@ import assertEvent from '@synthetixio/core-utils/utils/assertions/assert-event'; import { snapshotCheckpoint } from '@synthetixio/core-utils/utils/mocha/snapshot'; import { BigNumber, ethers } from 'ethers'; import hre from 'hardhat'; -import { bootstrapWithStakedPool } from '../../bootstrap'; +import { bn, bootstrapWithStakedPool } from '../../bootstrap'; import Permissions from '../../mixins/AccountRBACMixin.permissions'; import { verifyChecksCollateralEnabled, verifyUsesFeatureFlag } from '../../verifications'; @@ -443,4 +443,28 @@ describe('IssueUSDModule', function () { it('try to create debt beyond system max c ratio', exploit(2)); }); }); + + describe('establish a more stringent collateralization ratio for the pool', async () => { + before(restore); + + it('set the pool min collateal issuance ratio to 600%', async () => { + await systems() + .Core.connect(owner) + .setPoolCollateralIssuanceRatioD18(poolId, collateralAddress(), bn(6)); + }); + + it('verifies sufficient c-ratio', async () => { + const price = await systems().Core.getCollateralPrice(collateralAddress()); + + await assertRevert( + systems() + .Core.connect(user1) + .mintUsd(accountId, poolId, collateralAddress(), depositAmount), + `InsufficientCollateralRatio("${depositAmount}", "${depositAmount}", "${price}", "${bn( + 6 + ).toString()}")`, + 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 e08591a079..d633261d4d 100644 --- a/protocol/synthetix/test/integration/modules/core/PoolModuleFundAdmin.test.ts +++ b/protocol/synthetix/test/integration/modules/core/PoolModuleFundAdmin.test.ts @@ -5,7 +5,7 @@ import assertRevert from '@synthetixio/core-utils/utils/assertions/assert-revert import { snapshotCheckpoint } from '@synthetixio/core-utils/utils/mocha/snapshot'; import { ethers } from 'ethers'; import hre from 'hardhat'; -import { bootstrapWithMockMarketAndPool } from '../../bootstrap'; +import { bn, bootstrapWithMockMarketAndPool } from '../../bootstrap'; import { fastForwardTo, getTime } from '@synthetixio/core-utils/utils/hardhat/rpc'; describe('PoolModule Admin', function () { @@ -25,6 +25,7 @@ describe('PoolModule Admin', function () { let owner: ethers.Signer, user1: ethers.Signer, user2: ethers.Signer; const secondPoolId = 3384692; + const thirdPoolId = 3384633; const One = ethers.utils.parseEther('1'); const Hundred = ethers.utils.parseEther('100'); @@ -683,4 +684,104 @@ describe('PoolModule Admin', function () { }); }); }); + + describe('disable/enable collateral for a pool ', async () => { + before(restore); + + before('give user1 permission to create pool', async () => { + await systems() + .Core.connect(owner) + .addToFeatureFlagAllowlist( + ethers.utils.formatBytes32String('createPool'), + user1.getAddress() + ); + }); + + before('create a pool', async () => { + await ( + await systems() + .Core.connect(user1) + .createPool(thirdPoolId, await user1.getAddress()) + ).wait(); + }); + + it('only works for owner', async () => { + await assertRevert( + systems() + .Core.connect(user2) + .enablePoolCollateralDelegation(thirdPoolId, collateralAddress()), + `Unauthorized("${await user2.getAddress()}")`, + systems().Core + ); + }); + + 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) + .disablePoolCollateralDelegation(thirdPoolId, collateralAddress()); + }); + + it('collateral is disabled for the pool', async () => { + await assert.equal( + await systems().Core.isDelegationEnabledByPool(thirdPoolId, collateralAddress()), + false + ); + }); + }); + + describe('setPoolCollateralIssuanceRatioD18()', async () => { + before(restore); + + before('give user1 permission to create pool', async () => { + await systems() + .Core.connect(owner) + .addToFeatureFlagAllowlist( + ethers.utils.formatBytes32String('createPool'), + user1.getAddress() + ); + }); + + before('create a pool', async () => { + await ( + await systems() + .Core.connect(user1) + .createPool(thirdPoolId, await user1.getAddress()) + ).wait(); + }); + + it('only works for owner', async () => { + await assertRevert( + systems() + .Core.connect(user2) + .setPoolCollateralIssuanceRatioD18(thirdPoolId, collateralAddress(), bn(2)), + `Unauthorized("${await user2.getAddress()}")`, + systems().Core + ); + }); + + it('min collateral ratio is set to zero for the pool by default', async () => { + await assert.equal( + await systems().Core.getPoolCollateralIssuanceRatioD18(thirdPoolId, collateralAddress()), + 0 + ); + }); + + it('set the pool collateal issuance ratio to 200%', async () => { + await systems() + .Core.connect(user1) + .setPoolCollateralIssuanceRatioD18(thirdPoolId, collateralAddress(), bn(2)); + + await assertBn.equal( + await systems().Core.getPoolCollateralIssuanceRatioD18(thirdPoolId, collateralAddress()), + 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 d73c2354a2..66d3d52af8 100644 --- a/protocol/synthetix/test/integration/modules/core/VaultModule.test.ts +++ b/protocol/synthetix/test/integration/modules/core/VaultModule.test.ts @@ -277,7 +277,7 @@ describe('VaultModule', function () { ) ); - describe('when collateral is disabled', async () => { + describe('when collateral is disabled by system', async () => { const restore = snapshotCheckpoint(provider); after(restore); @@ -314,6 +314,65 @@ describe('VaultModule', function () { }); }); + describe('when collateral is disabled by pool owner', async () => { + const restore = snapshotCheckpoint(provider); + after(restore); + + const fakeVaultId = 93729021; + + before('create empty vault', async () => { + await systems().Core.createPool(fakeVaultId, await user1.getAddress()); + }); + + before('enable collateral for the system', async () => { + const beforeConfiguration = await systems().Core.getCollateralConfiguration( + collateralAddress() + ); + + await systems() + .Core.connect(owner) + .configureCollateral({ ...beforeConfiguration, depositingEnabled: true }); + }); + + // fails when collateral is disabled for the pool by pool owner + before('disable collateral for the pool by the pool owner', async () => { + await systems().Core.connect(user1).disablePoolCollateralDelegation(fakeVaultId, collateralAddress()); + }); + + // fails when collateral is disabled for the pool by pool owner + it('fails when trying to open delegation position with disabled collateral', async () => { + await assertRevert( + systems() + .Core.connect(user1) + .delegateCollateral( + accountId, + fakeVaultId, + collateralAddress(), + depositAmount.div(50), + ethers.utils.parseEther('1') + ), + `PoolCollateralIsDisabled("${collateralAddress()}", "${fakeVaultId}")`, + systems().Core + ); + }); + + it('collateral is enabled by the pool owner', async () => { + await systems().Core.connect(user1).enablePoolCollateralDelegation(fakeVaultId, collateralAddress()); + }); + + it('the delegation works as expected with the enabled collateral', async () => { + await systems() + .Core.connect(user1) + .delegateCollateral( + accountId, + fakeVaultId, + collateralAddress(), + depositAmount.div(50), + ethers.utils.parseEther('1') + ); + }); + }); + it( 'user1 has expected initial position', verifyAccountState(accountId, poolId, depositAmount, 0) diff --git a/protocol/synthetix/test/integration/storage/CollateralConfiguration.test.ts b/protocol/synthetix/test/integration/storage/CollateralConfiguration.test.ts index f1061921c6..3e58dd5a08 100644 --- a/protocol/synthetix/test/integration/storage/CollateralConfiguration.test.ts +++ b/protocol/synthetix/test/integration/storage/CollateralConfiguration.test.ts @@ -48,7 +48,8 @@ describe('CollateralConfiguration', function () { systems().Core.CollateralConfiguration_verifyIssuanceRatio( fakeCollateral.address, 100, - 499 + 499, + 0 ), 'InsufficientCollateralRatio("499", "100", "4990000000000000000", "5000000000000000000")', systems().Core @@ -59,23 +60,31 @@ describe('CollateralConfiguration', function () { await systems().Core.CollateralConfiguration_verifyIssuanceRatio( fakeCollateral.address, 100, - 500 + 500, + 0 ); await systems().Core.CollateralConfiguration_verifyIssuanceRatio( fakeCollateral.address, 100, - 1000 + 1000, + 0 ); await systems().Core.CollateralConfiguration_verifyIssuanceRatio( fakeCollateral.address, 0, - 1000 + 1000, + 0 ); }); it('edge case: fails if positive debt with no collateral', async () => { await assertRevert( - systems().Core.CollateralConfiguration_verifyIssuanceRatio(fakeCollateral.address, 100, 0), + systems().Core.CollateralConfiguration_verifyIssuanceRatio( + fakeCollateral.address, + 100, + 0, + 0 + ), 'InsufficientCollateralRatio("0", "100", "0", "5000000000000000000")', systems().Core ); From c5c472968c75597f0b95ea9f5e3413424c8dffff Mon Sep 17 00:00:00 2001 From: Peiman Date: Thu, 13 Jul 2023 00:53:13 +0330 Subject: [PATCH 02/63] fix: linting issue --- .../test/integration/modules/core/VaultModule.test.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/protocol/synthetix/test/integration/modules/core/VaultModule.test.ts b/protocol/synthetix/test/integration/modules/core/VaultModule.test.ts index 66d3d52af8..3fc1d3a5a9 100644 --- a/protocol/synthetix/test/integration/modules/core/VaultModule.test.ts +++ b/protocol/synthetix/test/integration/modules/core/VaultModule.test.ts @@ -336,7 +336,9 @@ describe('VaultModule', function () { // fails when collateral is disabled for the pool by pool owner before('disable collateral for the pool by the pool owner', async () => { - await systems().Core.connect(user1).disablePoolCollateralDelegation(fakeVaultId, collateralAddress()); + await systems() + .Core.connect(user1) + .disablePoolCollateralDelegation(fakeVaultId, collateralAddress()); }); // fails when collateral is disabled for the pool by pool owner @@ -357,7 +359,9 @@ describe('VaultModule', function () { }); it('collateral is enabled by the pool owner', async () => { - await systems().Core.connect(user1).enablePoolCollateralDelegation(fakeVaultId, collateralAddress()); + await systems() + .Core.connect(user1) + .enablePoolCollateralDelegation(fakeVaultId, collateralAddress()); }); it('the delegation works as expected with the enabled collateral', async () => { From 7bffd131a700d8ff58971664e5098e299bd4c040 Mon Sep 17 00:00:00 2001 From: Noisekit Date: Thu, 13 Jul 2023 07:19:19 +0800 Subject: [PATCH 03/63] Update Perps subgraph (#1718) --- .prettierignore | 6 +- markets/perps-market/subgraph/.gitignore | 6 +- .../subgraph/.yarn/install-state.gz | Bin 448705 -> 0 bytes .../subgraph/abis/PerpsMarketProxy.json | 3372 ----------------- markets/perps-market/subgraph/codegen.js | 44 + .../PerpsMarketProxy.ts | 272 +- markets/perps-market/subgraph/networks.json | 6 +- markets/perps-market/subgraph/package.json | 15 +- markets/perps-market/subgraph/src/account.ts | 2 +- markets/perps-market/subgraph/src/market.ts | 12 +- markets/perps-market/subgraph/src/orders.ts | 2 +- .../subgraph/src/settlementStrategies.ts | 2 +- .../perps-market/subgraph/subgraph.base.yaml | 18 +- yarn.lock | 2 + 14 files changed, 228 insertions(+), 3531 deletions(-) delete mode 100644 markets/perps-market/subgraph/.yarn/install-state.gz delete mode 100644 markets/perps-market/subgraph/abis/PerpsMarketProxy.json create mode 100755 markets/perps-market/subgraph/codegen.js rename markets/perps-market/subgraph/generated/{PerpsMarket => PerpsMarketProxy}/PerpsMarketProxy.ts (95%) diff --git a/.prettierignore b/.prettierignore index 90b2a9a3f5..d58cdeafdf 100644 --- a/.prettierignore +++ b/.prettierignore @@ -14,4 +14,8 @@ markets/*/test/generated *Router.sol .yarnrc.yml lerna.json -*.hbs \ No newline at end of file +*.hbs +**/subgraph/deployments/ +**/artifacts/ +**/cache/ +**/docs/ diff --git a/markets/perps-market/subgraph/.gitignore b/markets/perps-market/subgraph/.gitignore index 49320e80af..a3e826de17 100644 --- a/markets/perps-market/subgraph/.gitignore +++ b/markets/perps-market/subgraph/.gitignore @@ -1,8 +1,6 @@ -**/build -**/dist -**/node_modules - .bin/ tests/.bin/ tests/.latest.json subgraph.yaml +deployments/ +build/ diff --git a/markets/perps-market/subgraph/.yarn/install-state.gz b/markets/perps-market/subgraph/.yarn/install-state.gz deleted file mode 100644 index 48dc3bac6d10cea3665e548157cf13db20785114..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 448705 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

?_Ol9jkv=61gzbFF1~f|H#KYCZat@v~VY1-D^!M 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

-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 diff --git a/markets/perps-market/subgraph/abis/PerpsMarketProxy.json b/markets/perps-market/subgraph/abis/PerpsMarketProxy.json deleted file mode 100644 index cd7aee84ac..0000000000 --- a/markets/perps-market/subgraph/abis/PerpsMarketProxy.json +++ /dev/null @@ -1,3372 +0,0 @@ -{ - "address": "0x54D71285871C5a0914F5B53740b70bA3eDb51Fbb", - "abi": [ - { - "inputs": [ - { - "internalType": "bytes32", - "name": "which", - "type": "bytes32" - } - ], - "name": "FeatureUnavailable", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint128", - "name": "accountId", - "type": "uint128" - } - ], - "name": "InvalidAccountId", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "permission", - "type": "bytes32" - } - ], - "name": "InvalidPermission", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "origin", - "type": "address" - } - ], - "name": "OnlyAccountTokenProxy", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint128", - "name": "accountId", - "type": "uint128" - }, - { - "internalType": "bytes32", - "name": "permission", - "type": "bytes32" - }, - { - "internalType": "address", - "name": "target", - "type": "address" - } - ], - "name": "PermissionDenied", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint128", - "name": "accountId", - "type": "uint128" - }, - { - "internalType": "bytes32", - "name": "permission", - "type": "bytes32" - }, - { - "internalType": "address", - "name": "user", - "type": "address" - } - ], - "name": "PermissionNotGranted", - "type": "error" - }, - { - "inputs": [], - "name": "PositionOutOfBounds", - "type": "error" - }, - { - "inputs": [], - "name": "ValueAlreadyInSet", - "type": "error" - }, - { - "inputs": [], - "name": "ValueNotInSet", - "type": "error" - }, - { - "inputs": [], - "name": "ZeroAddress", - "type": "error" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint128", - "name": "accountId", - "type": "uint128" - }, - { - "indexed": true, - "internalType": "address", - "name": "owner", - "type": "address" - } - ], - "name": "AccountCreated", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint128", - "name": "accountId", - "type": "uint128" - }, - { - "indexed": true, - "internalType": "bytes32", - "name": "permission", - "type": "bytes32" - }, - { - "indexed": true, - "internalType": "address", - "name": "user", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "sender", - "type": "address" - } - ], - "name": "PermissionGranted", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint128", - "name": "accountId", - "type": "uint128" - }, - { - "indexed": true, - "internalType": "bytes32", - "name": "permission", - "type": "bytes32" - }, - { - "indexed": true, - "internalType": "address", - "name": "user", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "sender", - "type": "address" - } - ], - "name": "PermissionRevoked", - "type": "event" - }, - { - "inputs": [], - "name": "createAccount", - "outputs": [ - { - "internalType": "uint128", - "name": "accountId", - "type": "uint128" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint128", - "name": "requestedAccountId", - "type": "uint128" - } - ], - "name": "createAccount", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint128", - "name": "accountId", - "type": "uint128" - } - ], - "name": "getAccountLastInteraction", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint128", - "name": "accountId", - "type": "uint128" - } - ], - "name": "getAccountOwner", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint128", - "name": "accountId", - "type": "uint128" - } - ], - "name": "getAccountPermissions", - "outputs": [ - { - "components": [ - { - "internalType": "address", - "name": "user", - "type": "address" - }, - { - "internalType": "bytes32[]", - "name": "permissions", - "type": "bytes32[]" - } - ], - "internalType": "struct IAccountModule.AccountPermissions[]", - "name": "accountPerms", - "type": "tuple[]" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getAccountTokenAddress", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint128", - "name": "accountId", - "type": "uint128" - }, - { - "internalType": "bytes32", - "name": "permission", - "type": "bytes32" - }, - { - "internalType": "address", - "name": "user", - "type": "address" - } - ], - "name": "grantPermission", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint128", - "name": "accountId", - "type": "uint128" - }, - { - "internalType": "bytes32", - "name": "permission", - "type": "bytes32" - }, - { - "internalType": "address", - "name": "user", - "type": "address" - } - ], - "name": "hasPermission", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint128", - "name": "accountId", - "type": "uint128" - }, - { - "internalType": "bytes32", - "name": "permission", - "type": "bytes32" - }, - { - "internalType": "address", - "name": "user", - "type": "address" - } - ], - "name": "isAuthorized", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint128", - "name": "accountId", - "type": "uint128" - } - ], - "name": "notifyAccountTransfer", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint128", - "name": "accountId", - "type": "uint128" - }, - { - "internalType": "bytes32", - "name": "permission", - "type": "bytes32" - } - ], - "name": "renouncePermission", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint128", - "name": "accountId", - "type": "uint128" - }, - { - "internalType": "bytes32", - "name": "permission", - "type": "bytes32" - }, - { - "internalType": "address", - "name": "user", - "type": "address" - } - ], - "name": "revokePermission", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "expected", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "actual", - "type": "bytes32" - } - ], - "name": "MismatchAssociatedSystemKind", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "id", - "type": "bytes32" - } - ], - "name": "MissingAssociatedSystem", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "addr", - "type": "address" - } - ], - "name": "Unauthorized", - "type": "error" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "bytes32", - "name": "kind", - "type": "bytes32" - }, - { - "indexed": true, - "internalType": "bytes32", - "name": "id", - "type": "bytes32" - }, - { - "indexed": false, - "internalType": "address", - "name": "proxy", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "impl", - "type": "address" - } - ], - "name": "AssociatedSystemSet", - "type": "event" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "id", - "type": "bytes32" - } - ], - "name": "getAssociatedSystem", - "outputs": [ - { - "internalType": "address", - "name": "addr", - "type": "address" - }, - { - "internalType": "bytes32", - "name": "kind", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "id", - "type": "bytes32" - }, - { - "internalType": "string", - "name": "name", - "type": "string" - }, - { - "internalType": "string", - "name": "symbol", - "type": "string" - }, - { - "internalType": "string", - "name": "uri", - "type": "string" - }, - { - "internalType": "address", - "name": "impl", - "type": "address" - } - ], - "name": "initOrUpgradeNft", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "id", - "type": "bytes32" - }, - { - "internalType": "string", - "name": "name", - "type": "string" - }, - { - "internalType": "string", - "name": "symbol", - "type": "string" - }, - { - "internalType": "uint8", - "name": "decimals", - "type": "uint8" - }, - { - "internalType": "address", - "name": "impl", - "type": "address" - } - ], - "name": "initOrUpgradeToken", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "id", - "type": "bytes32" - }, - { - "internalType": "address", - "name": "endpoint", - "type": "address" - } - ], - "name": "registerUnmanagedSystem", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "implementation", - "type": "address" - } - ], - "name": "ImplementationIsSterile", - "type": "error" - }, - { - "inputs": [], - "name": "NoChange", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "contr", - "type": "address" - } - ], - "name": "NotAContract", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "addr", - "type": "address" - } - ], - "name": "NotNominated", - "type": "error" - }, - { - "inputs": [], - "name": "UpgradeSimulationFailed", - "type": "error" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "oldOwner", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "newOwner", - "type": "address" - } - ], - "name": "OwnerChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "newOwner", - "type": "address" - } - ], - "name": "OwnerNominated", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "self", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "implementation", - "type": "address" - } - ], - "name": "Upgraded", - "type": "event" - }, - { - "inputs": [], - "name": "acceptOwnership", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "getImplementation", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "newNominatedOwner", - "type": "address" - } - ], - "name": "nominateNewOwner", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "nominatedOwner", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "owner", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "renounceNomination", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "newImplementation", - "type": "address" - } - ], - "name": "simulateUpgradeTo", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "newImplementation", - "type": "address" - } - ], - "name": "upgradeTo", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "InvalidMarketOwner", - "type": "error" - }, - { - "inputs": [], - "name": "OverflowInt256ToUint256", - "type": "error" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint128", - "name": "perpsMarketId", - "type": "uint128" - }, - { - "indexed": false, - "internalType": "address", - "name": "oldOwner", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "newOwner", - "type": "address" - } - ], - "name": "MarketOwnerChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint128", - "name": "perpsMarketId", - "type": "uint128" - }, - { - "indexed": false, - "internalType": "address", - "name": "newNominatedOwner", - "type": "address" - } - ], - "name": "MarketOwnerNominated", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint128", - "name": "perpsMarketId", - "type": "uint128" - }, - { - "indexed": false, - "internalType": "bytes32", - "name": "feedId", - "type": "bytes32" - } - ], - "name": "MarketPriceDataUpdated", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint128", - "name": "perpsMarketId", - "type": "uint128" - }, - { - "indexed": true, - "internalType": "address", - "name": "marketOwner", - "type": "address" - }, - { - "indexed": false, - "internalType": "string", - "name": "marketName", - "type": "string" - }, - { - "indexed": false, - "internalType": "string", - "name": "marketSymbol", - "type": "string" - } - ], - "name": "MarketRegistered", - "type": "event" - }, - { - "inputs": [ - { - "internalType": "uint128", - "name": "perpsMarketId", - "type": "uint128" - } - ], - "name": "acceptMarketOwnership", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "string", - "name": "marketName", - "type": "string" - }, - { - "internalType": "string", - "name": "marketSymbol", - "type": "string" - }, - { - "internalType": "address", - "name": "marketOwner", - "type": "address" - } - ], - "name": "createMarket", - "outputs": [ - { - "internalType": "uint128", - "name": "", - "type": "uint128" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint128", - "name": "perpsMarketId", - "type": "uint128" - } - ], - "name": "getMarketOwner", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint128", - "name": "perpsMarketId", - "type": "uint128" - } - ], - "name": "minimumCredit", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint128", - "name": "perpsMarketId", - "type": "uint128" - } - ], - "name": "name", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint128", - "name": "perpsMarketId", - "type": "uint128" - }, - { - "internalType": "address", - "name": "newNominatedOwner", - "type": "address" - } - ], - "name": "nominateMarketOwner", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint128", - "name": "perpsMarketId", - "type": "uint128" - } - ], - "name": "reportedDebt", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "contract ISpotMarketSystem", - "name": "spotMarket", - "type": "address" - } - ], - "name": "setSpotMarket", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "contract ISynthetixSystem", - "name": "synthetix", - "type": "address" - } - ], - "name": "setSynthetix", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes4", - "name": "interfaceId", - "type": "bytes4" - } - ], - "name": "supportsInterface", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint128", - "name": "perpsMarketId", - "type": "uint128" - } - ], - "name": "symbol", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint128", - "name": "perpsMarketId", - "type": "uint128" - }, - { - "internalType": "bytes32", - "name": "feedId", - "type": "bytes32" - } - ], - "name": "updatePriceData", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint128", - "name": "accountId", - "type": "uint128" - } - ], - "name": "AccountLiquidatable", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint128", - "name": "accountId", - "type": "uint128" - } - ], - "name": "AccountNotFound", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint128", - "name": "synthMarketId", - "type": "uint128" - }, - { - "internalType": "uint256", - "name": "collateralAmount", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "withdrawAmount", - "type": "uint256" - } - ], - "name": "InsufficientCollateral", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "available", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "required", - "type": "uint256" - } - ], - "name": "InsufficientCollateralAvailableForWithdraw", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "int256", - "name": "amountDelta", - "type": "int256" - } - ], - "name": "InvalidAmountDelta", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint128", - "name": "marketId", - "type": "uint128" - } - ], - "name": "InvalidMarket", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint128", - "name": "synthMarketId", - "type": "uint128" - }, - { - "internalType": "uint256", - "name": "maxAmount", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "collateralAmount", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "depositAmount", - "type": "uint256" - } - ], - "name": "MaxCollateralExceeded", - "type": "error" - }, - { - "inputs": [], - "name": "OverflowUint128ToInt128", - "type": "error" - }, - { - "inputs": [], - "name": "OverflowUint256ToInt256", - "type": "error" - }, - { - "inputs": [], - "name": "OverflowUint256ToUint128", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint128", - "name": "marketId", - "type": "uint128" - } - ], - "name": "PriceFeedNotSet", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint128", - "name": "synthMarketId", - "type": "uint128" - } - ], - "name": "SynthNotEnabledForCollateral", - "type": "error" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint128", - "name": "accountId", - "type": "uint128" - }, - { - "indexed": true, - "internalType": "uint128", - "name": "synthMarketId", - "type": "uint128" - }, - { - "indexed": true, - "internalType": "int256", - "name": "amountDelta", - "type": "int256" - }, - { - "indexed": false, - "internalType": "address", - "name": "sender", - "type": "address" - } - ], - "name": "CollateralModified", - "type": "event" - }, - { - "inputs": [ - { - "internalType": "uint128", - "name": "accountId", - "type": "uint128" - }, - { - "internalType": "uint128", - "name": "marketId", - "type": "uint128" - } - ], - "name": "getAsyncOrderClaim", - "outputs": [ - { - "components": [ - { - "internalType": "uint128", - "name": "accountId", - "type": "uint128" - }, - { - "internalType": "uint128", - "name": "marketId", - "type": "uint128" - }, - { - "internalType": "int128", - "name": "sizeDelta", - "type": "int128" - }, - { - "internalType": "uint128", - "name": "settlementStrategyId", - "type": "uint128" - }, - { - "internalType": "uint256", - "name": "settlementTime", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "acceptablePrice", - "type": "uint256" - }, - { - "internalType": "bytes32", - "name": "trackingCode", - "type": "bytes32" - } - ], - "internalType": "struct AsyncOrder.Data", - "name": "", - "type": "tuple" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint128", - "name": "accountId", - "type": "uint128" - } - ], - "name": "getAvailableMargin", - "outputs": [ - { - "internalType": "int256", - "name": "", - "type": "int256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint128", - "name": "accountId", - "type": "uint128" - }, - { - "internalType": "uint128", - "name": "marketId", - "type": "uint128" - } - ], - "name": "getOpenPosition", - "outputs": [ - { - "internalType": "int256", - "name": "", - "type": "int256" - }, - { - "internalType": "int256", - "name": "", - "type": "int256" - }, - { - "internalType": "int256", - "name": "", - "type": "int256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint128", - "name": "accountId", - "type": "uint128" - }, - { - "internalType": "uint128", - "name": "synthMarketId", - "type": "uint128" - }, - { - "internalType": "int256", - "name": "amountDelta", - "type": "int256" - } - ], - "name": "modifyCollateral", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint128", - "name": "accountId", - "type": "uint128" - } - ], - "name": "totalAccountOpenInterest", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint128", - "name": "accountId", - "type": "uint128" - } - ], - "name": "totalCollateralValue", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint128", - "name": "marketId", - "type": "uint128" - } - ], - "name": "currentFundingRate", - "outputs": [ - { - "internalType": "int256", - "name": "", - "type": "int256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint128", - "name": "marketId", - "type": "uint128" - } - ], - "name": "currentFundingVelocity", - "outputs": [ - { - "internalType": "int256", - "name": "", - "type": "int256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint128", - "name": "marketId", - "type": "uint128" - }, - { - "internalType": "int256", - "name": "orderSize", - "type": "int256" - }, - { - "internalType": "uint256", - "name": "price", - "type": "uint256" - } - ], - "name": "fillPrice", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint128", - "name": "marketId", - "type": "uint128" - } - ], - "name": "getMarketSummary", - "outputs": [ - { - "components": [ - { - "internalType": "int256", - "name": "skew", - "type": "int256" - }, - { - "internalType": "uint256", - "name": "size", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "maxOpenInterest", - "type": "uint256" - }, - { - "internalType": "int256", - "name": "currentFundingRate", - "type": "int256" - }, - { - "internalType": "int256", - "name": "currentFundingVelocity", - "type": "int256" - }, - { - "internalType": "uint256", - "name": "indexPrice", - "type": "uint256" - } - ], - "internalType": "struct IPerpsMarketModule.MarketSummary", - "name": "summary", - "type": "tuple" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint128", - "name": "marketId", - "type": "uint128" - } - ], - "name": "indexPrice", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint128", - "name": "marketId", - "type": "uint128" - } - ], - "name": "maxOpenInterest", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint128", - "name": "marketId", - "type": "uint128" - } - ], - "name": "size", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint128", - "name": "marketId", - "type": "uint128" - } - ], - "name": "skew", - "outputs": [ - { - "internalType": "int256", - "name": "", - "type": "int256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "acceptablePrice", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "fillPrice", - "type": "uint256" - } - ], - "name": "AcceptablePriceExceeded", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "int256", - "name": "availableMargin", - "type": "int256" - }, - { - "internalType": "uint256", - "name": "minMargin", - "type": "uint256" - } - ], - "name": "InsufficientMargin", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "leftover", - "type": "uint256" - } - ], - "name": "InsufficientMarginError", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint128", - "name": "settlementStrategyId", - "type": "uint128" - } - ], - "name": "InvalidSettlementStrategy", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "sender", - "type": "address" - }, - { - "internalType": "string[]", - "name": "urls", - "type": "string[]" - }, - { - "internalType": "bytes", - "name": "callData", - "type": "bytes" - }, - { - "internalType": "bytes4", - "name": "callbackFunction", - "type": "bytes4" - }, - { - "internalType": "bytes", - "name": "extraData", - "type": "bytes" - } - ], - "name": "OffchainLookup", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint128", - "name": "marketId", - "type": "uint128" - }, - { - "internalType": "uint128", - "name": "accountId", - "type": "uint128" - } - ], - "name": "OrderAlreadyCommitted", - "type": "error" - }, - { - "inputs": [], - "name": "OrderNotValid", - "type": "error" - }, - { - "inputs": [], - "name": "OverflowInt256ToInt128", - "type": "error" - }, - { - "inputs": [], - "name": "OverflowUint256ToUint64", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "deviation", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "tolerance", - "type": "uint256" - } - ], - "name": "PriceDeviationToleranceExceeded", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "enum SettlementStrategy.Type", - "name": "strategyType", - "type": "uint8" - } - ], - "name": "SettlementStrategyNotFound", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "timestamp", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "settlementTime", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "settlementExpiration", - "type": "uint256" - } - ], - "name": "SettlementWindowExpired", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "timestamp", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "settlementTime", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "settlementExpiration", - "type": "uint256" - } - ], - "name": "SettlementWindowNotExpired", - "type": "error" - }, - { - "inputs": [], - "name": "ZeroSizeOrder", - "type": "error" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint128", - "name": "marketId", - "type": "uint128" - }, - { - "indexed": true, - "internalType": "uint128", - "name": "accountId", - "type": "uint128" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "settlementTime", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "acceptablePrice", - "type": "uint256" - } - ], - "name": "OrderCanceled", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint128", - "name": "marketId", - "type": "uint128" - }, - { - "indexed": true, - "internalType": "uint128", - "name": "accountId", - "type": "uint128" - }, - { - "indexed": true, - "internalType": "enum SettlementStrategy.Type", - "name": "orderType", - "type": "uint8" - }, - { - "indexed": false, - "internalType": "int128", - "name": "sizeDelta", - "type": "int128" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "acceptablePrice", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "settlementTime", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "expirationTime", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "bytes32", - "name": "trackingCode", - "type": "bytes32" - }, - { - "indexed": false, - "internalType": "address", - "name": "sender", - "type": "address" - } - ], - "name": "OrderCommitted", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint128", - "name": "marketId", - "type": "uint128" - }, - { - "indexed": true, - "internalType": "uint128", - "name": "accountId", - "type": "uint128" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "fillPrice", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "int256", - "name": "accountPnlRealized", - "type": "int256" - }, - { - "indexed": false, - "internalType": "int128", - "name": "newSize", - "type": "int128" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "collectedFees", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "settelementReward", - "type": "uint256" - }, - { - "indexed": true, - "internalType": "bytes32", - "name": "trackingCode", - "type": "bytes32" - }, - { - "indexed": false, - "internalType": "address", - "name": "settler", - "type": "address" - } - ], - "name": "OrderSettled", - "type": "event" - }, - { - "inputs": [], - "name": "PRECISION", - "outputs": [ - { - "internalType": "int256", - "name": "", - "type": "int256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint128", - "name": "marketId", - "type": "uint128" - }, - { - "internalType": "uint128", - "name": "accountId", - "type": "uint128" - } - ], - "name": "cancelOrder", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "components": [ - { - "internalType": "uint128", - "name": "marketId", - "type": "uint128" - }, - { - "internalType": "uint128", - "name": "accountId", - "type": "uint128" - }, - { - "internalType": "int128", - "name": "sizeDelta", - "type": "int128" - }, - { - "internalType": "uint128", - "name": "settlementStrategyId", - "type": "uint128" - }, - { - "internalType": "uint256", - "name": "acceptablePrice", - "type": "uint256" - }, - { - "internalType": "bytes32", - "name": "trackingCode", - "type": "bytes32" - } - ], - "internalType": "struct AsyncOrder.OrderCommitmentRequest", - "name": "commitment", - "type": "tuple" - } - ], - "name": "commitOrder", - "outputs": [ - { - "components": [ - { - "internalType": "uint128", - "name": "accountId", - "type": "uint128" - }, - { - "internalType": "uint128", - "name": "marketId", - "type": "uint128" - }, - { - "internalType": "int128", - "name": "sizeDelta", - "type": "int128" - }, - { - "internalType": "uint128", - "name": "settlementStrategyId", - "type": "uint128" - }, - { - "internalType": "uint256", - "name": "settlementTime", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "acceptablePrice", - "type": "uint256" - }, - { - "internalType": "bytes32", - "name": "trackingCode", - "type": "bytes32" - } - ], - "internalType": "struct AsyncOrder.Data", - "name": "retOrder", - "type": "tuple" - }, - { - "internalType": "uint256", - "name": "fees", - "type": "uint256" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint128", - "name": "marketId", - "type": "uint128" - }, - { - "internalType": "uint128", - "name": "accountId", - "type": "uint128" - } - ], - "name": "getOrder", - "outputs": [ - { - "components": [ - { - "internalType": "uint128", - "name": "accountId", - "type": "uint128" - }, - { - "internalType": "uint128", - "name": "marketId", - "type": "uint128" - }, - { - "internalType": "int128", - "name": "sizeDelta", - "type": "int128" - }, - { - "internalType": "uint128", - "name": "settlementStrategyId", - "type": "uint128" - }, - { - "internalType": "uint256", - "name": "settlementTime", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "acceptablePrice", - "type": "uint256" - }, - { - "internalType": "bytes32", - "name": "trackingCode", - "type": "bytes32" - } - ], - "internalType": "struct AsyncOrder.Data", - "name": "", - "type": "tuple" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint128", - "name": "marketId", - "type": "uint128" - }, - { - "internalType": "uint128", - "name": "accountId", - "type": "uint128" - } - ], - "name": "settle", - "outputs": [], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes", - "name": "result", - "type": "bytes" - }, - { - "internalType": "bytes", - "name": "extraData", - "type": "bytes" - } - ], - "name": "settlePythOrder", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "bytes32", - "name": "feature", - "type": "bytes32" - }, - { - "indexed": false, - "internalType": "bool", - "name": "allowAll", - "type": "bool" - } - ], - "name": "FeatureFlagAllowAllSet", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "bytes32", - "name": "feature", - "type": "bytes32" - }, - { - "indexed": false, - "internalType": "address", - "name": "account", - "type": "address" - } - ], - "name": "FeatureFlagAllowlistAdded", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "bytes32", - "name": "feature", - "type": "bytes32" - }, - { - "indexed": false, - "internalType": "address", - "name": "account", - "type": "address" - } - ], - "name": "FeatureFlagAllowlistRemoved", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "bytes32", - "name": "feature", - "type": "bytes32" - }, - { - "indexed": false, - "internalType": "address[]", - "name": "deniers", - "type": "address[]" - } - ], - "name": "FeatureFlagDeniersReset", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "bytes32", - "name": "feature", - "type": "bytes32" - }, - { - "indexed": false, - "internalType": "bool", - "name": "denyAll", - "type": "bool" - } - ], - "name": "FeatureFlagDenyAllSet", - "type": "event" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "feature", - "type": "bytes32" - }, - { - "internalType": "address", - "name": "account", - "type": "address" - } - ], - "name": "addToFeatureFlagAllowlist", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "feature", - "type": "bytes32" - } - ], - "name": "getDeniers", - "outputs": [ - { - "internalType": "address[]", - "name": "", - "type": "address[]" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "feature", - "type": "bytes32" - } - ], - "name": "getFeatureFlagAllowAll", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "feature", - "type": "bytes32" - } - ], - "name": "getFeatureFlagAllowlist", - "outputs": [ - { - "internalType": "address[]", - "name": "", - "type": "address[]" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "feature", - "type": "bytes32" - } - ], - "name": "getFeatureFlagDenyAll", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "feature", - "type": "bytes32" - }, - { - "internalType": "address", - "name": "account", - "type": "address" - } - ], - "name": "isFeatureAllowed", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "feature", - "type": "bytes32" - }, - { - "internalType": "address", - "name": "account", - "type": "address" - } - ], - "name": "removeFromFeatureFlagAllowlist", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "feature", - "type": "bytes32" - }, - { - "internalType": "address[]", - "name": "deniers", - "type": "address[]" - } - ], - "name": "setDeniers", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "feature", - "type": "bytes32" - }, - { - "internalType": "bool", - "name": "allowAll", - "type": "bool" - } - ], - "name": "setFeatureFlagAllowAll", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "feature", - "type": "bytes32" - }, - { - "internalType": "bool", - "name": "denyAll", - "type": "bool" - } - ], - "name": "setFeatureFlagDenyAll", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint128", - "name": "accountId", - "type": "uint128" - } - ], - "name": "NotEligibleForLiquidation", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint128", - "name": "accountId", - "type": "uint128" - } - ], - "name": "liquidate", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "liquidateFlagged", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "marketOwner", - "type": "address" - }, - { - "internalType": "address", - "name": "sender", - "type": "address" - } - ], - "name": "OnlyMarketOwner", - "type": "error" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint128", - "name": "marketId", - "type": "uint128" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "skewScale", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "maxFundingVelocity", - "type": "uint256" - } - ], - "name": "FundingParametersSet", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint128", - "name": "marketId", - "type": "uint128" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "initialMarginFraction", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "maintenanceMarginFraction", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "liquidationRewardRatioD18", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "maxLiquidationLimitAccumulationMultiplier", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "maxSecondsInLiquidationWindow", - "type": "uint256" - } - ], - "name": "LiquidationParametersSet", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint128", - "name": "marketId", - "type": "uint128" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "lockedOiPercent", - "type": "uint256" - } - ], - "name": "LockedOiPercentSet", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint128", - "name": "marketId", - "type": "uint128" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "maxMarketValue", - "type": "uint256" - } - ], - "name": "MaxMarketValueSet", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint128", - "name": "marketId", - "type": "uint128" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "makerFeeRatio", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "takerFeeRatio", - "type": "uint256" - } - ], - "name": "OrderFeesSet", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint128", - "name": "marketId", - "type": "uint128" - }, - { - "components": [ - { - "internalType": "enum SettlementStrategy.Type", - "name": "strategyType", - "type": "uint8" - }, - { - "internalType": "uint256", - "name": "settlementDelay", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "settlementWindowDuration", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "priceWindowDuration", - "type": "uint256" - }, - { - "internalType": "address", - "name": "priceVerificationContract", - "type": "address" - }, - { - "internalType": "bytes32", - "name": "feedId", - "type": "bytes32" - }, - { - "internalType": "string", - "name": "url", - "type": "string" - }, - { - "internalType": "uint256", - "name": "settlementReward", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "priceDeviationTolerance", - "type": "uint256" - }, - { - "internalType": "bool", - "name": "disabled", - "type": "bool" - } - ], - "indexed": false, - "internalType": "struct SettlementStrategy.Data", - "name": "strategy", - "type": "tuple" - }, - { - "indexed": true, - "internalType": "uint256", - "name": "strategyId", - "type": "uint256" - } - ], - "name": "SettlementStrategyAdded", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint128", - "name": "marketId", - "type": "uint128" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "strategyId", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "bool", - "name": "enabled", - "type": "bool" - } - ], - "name": "SettlementStrategyEnabled", - "type": "event" - }, - { - "inputs": [ - { - "internalType": "uint128", - "name": "marketId", - "type": "uint128" - }, - { - "components": [ - { - "internalType": "enum SettlementStrategy.Type", - "name": "strategyType", - "type": "uint8" - }, - { - "internalType": "uint256", - "name": "settlementDelay", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "settlementWindowDuration", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "priceWindowDuration", - "type": "uint256" - }, - { - "internalType": "address", - "name": "priceVerificationContract", - "type": "address" - }, - { - "internalType": "bytes32", - "name": "feedId", - "type": "bytes32" - }, - { - "internalType": "string", - "name": "url", - "type": "string" - }, - { - "internalType": "uint256", - "name": "settlementReward", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "priceDeviationTolerance", - "type": "uint256" - }, - { - "internalType": "bool", - "name": "disabled", - "type": "bool" - } - ], - "internalType": "struct SettlementStrategy.Data", - "name": "strategy", - "type": "tuple" - } - ], - "name": "addSettlementStrategy", - "outputs": [ - { - "internalType": "uint256", - "name": "strategyId", - "type": "uint256" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint128", - "name": "marketId", - "type": "uint128" - } - ], - "name": "getFundingParameters", - "outputs": [ - { - "internalType": "uint256", - "name": "skewScale", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "maxFundingVelocity", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint128", - "name": "marketId", - "type": "uint128" - } - ], - "name": "getLiquidationParameters", - "outputs": [ - { - "internalType": "uint256", - "name": "initialMarginFraction", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "maintenanceMarginFraction", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "liquidationRewardRatioD18", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "maxLiquidationLimitAccumulationMultiplier", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "maxSecondsInLiquidationWindow", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint128", - "name": "marketId", - "type": "uint128" - } - ], - "name": "getLockedOiPercent", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint128", - "name": "marketId", - "type": "uint128" - } - ], - "name": "getMaxMarketValue", - "outputs": [ - { - "internalType": "uint256", - "name": "maxMarketValue", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint128", - "name": "marketId", - "type": "uint128" - } - ], - "name": "getOrderFees", - "outputs": [ - { - "internalType": "uint256", - "name": "makerFee", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "takerFee", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint128", - "name": "marketId", - "type": "uint128" - }, - { - "internalType": "uint256", - "name": "strategyId", - "type": "uint256" - } - ], - "name": "getSettlementStrategy", - "outputs": [ - { - "components": [ - { - "internalType": "enum SettlementStrategy.Type", - "name": "strategyType", - "type": "uint8" - }, - { - "internalType": "uint256", - "name": "settlementDelay", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "settlementWindowDuration", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "priceWindowDuration", - "type": "uint256" - }, - { - "internalType": "address", - "name": "priceVerificationContract", - "type": "address" - }, - { - "internalType": "bytes32", - "name": "feedId", - "type": "bytes32" - }, - { - "internalType": "string", - "name": "url", - "type": "string" - }, - { - "internalType": "uint256", - "name": "settlementReward", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "priceDeviationTolerance", - "type": "uint256" - }, - { - "internalType": "bool", - "name": "disabled", - "type": "bool" - } - ], - "internalType": "struct SettlementStrategy.Data", - "name": "settlementStrategy", - "type": "tuple" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint128", - "name": "marketId", - "type": "uint128" - }, - { - "internalType": "uint256", - "name": "skewScale", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "maxFundingVelocity", - "type": "uint256" - } - ], - "name": "setFundingParameters", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint128", - "name": "marketId", - "type": "uint128" - }, - { - "internalType": "uint256", - "name": "initialMarginFraction", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "maintenanceMarginFraction", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "liquidationRewardRatioD18", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "maxLiquidationLimitAccumulationMultiplier", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "maxSecondsInLiquidationWindow", - "type": "uint256" - } - ], - "name": "setLiquidationParameters", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint128", - "name": "marketId", - "type": "uint128" - }, - { - "internalType": "uint256", - "name": "lockedOiPercent", - "type": "uint256" - } - ], - "name": "setLockedOiPercent", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint128", - "name": "marketId", - "type": "uint128" - }, - { - "internalType": "uint256", - "name": "maxMarketValue", - "type": "uint256" - } - ], - "name": "setMaxMarketValue", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint128", - "name": "marketId", - "type": "uint128" - }, - { - "internalType": "uint256", - "name": "makerFeeRatio", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "takerFeeRatio", - "type": "uint256" - } - ], - "name": "setOrderFees", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint128", - "name": "marketId", - "type": "uint128" - }, - { - "internalType": "uint256", - "name": "strategyId", - "type": "uint256" - }, - { - "internalType": "bool", - "name": "enabled", - "type": "bool" - } - ], - "name": "setSettlementStrategyEnabled", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint256", - "name": "minLiquidationRewardUsd", - "type": "uint256" - }, - { - "indexed": true, - "internalType": "uint256", - "name": "maxLiquidationRewardUsd", - "type": "uint256" - } - ], - "name": "LiquidationRewardGuardsSet", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint128", - "name": "synthMarketId", - "type": "uint128" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "collateralAmount", - "type": "uint256" - } - ], - "name": "MaxCollateralAmountSet", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint128[]", - "name": "newSynthDeductionPriority", - "type": "uint128[]" - } - ], - "name": "SynthDeductionPrioritySet", - "type": "event" - }, - { - "inputs": [], - "name": "getLiquidationRewardGuards", - "outputs": [ - { - "internalType": "uint256", - "name": "minLiquidationRewardUsd", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "maxLiquidationRewardUsd", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint128", - "name": "synthMarketId", - "type": "uint128" - } - ], - "name": "getMaxCollateralAmount", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getSynthDeductionPriority", - "outputs": [ - { - "internalType": "uint128[]", - "name": "", - "type": "uint128[]" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "minLiquidationRewardUsd", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "maxLiquidationRewardUsd", - "type": "uint256" - } - ], - "name": "setLiquidationRewardGuards", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint128", - "name": "synthMarketId", - "type": "uint128" - }, - { - "internalType": "uint256", - "name": "collateralAmount", - "type": "uint256" - } - ], - "name": "setMaxCollateralAmount", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint128[]", - "name": "newSynthDeductionPriority", - "type": "uint128[]" - } - ], - "name": "setSynthDeductionPriority", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - } - ], - "deployTxnHash": "", - "sourceName": "", - "contractName": "", - "deployedOn": "invoke.upgrade_proxy" -} diff --git a/markets/perps-market/subgraph/codegen.js b/markets/perps-market/subgraph/codegen.js new file mode 100755 index 0000000000..5e83a59a9e --- /dev/null +++ b/markets/perps-market/subgraph/codegen.js @@ -0,0 +1,44 @@ +#!/usr/bin/env node + +const ethers = require('ethers'); +const fs = require('fs'); +const prettier = require('prettier'); + +const [networkName] = process.argv.slice(2); +const networkId = { + mainnet: 1, + 'optimism-mainnet': 10, + goerli: 5, + 'optimism-goerli': 420, +}[networkName]; + +const graphNetworkName = { + mainnet: 'mainnet', + 'optimism-mainnet': 'optimism', + goerli: 'goerli', + 'optimism-goerli': 'optimism-goerli', +}[networkName]; + +async function run() { + const provider = new ethers.providers.InfuraProvider(networkId, process.env.INFURA_KEY); + + const networks = JSON.parse(fs.readFileSync('./networks.json', 'utf8')); + + networks[graphNetworkName].PerpsMarketProxy.address = + require(`./deployments/${networkName}/PerpsMarketProxy.json`).address; + + const deployTx = require(`./deployments/${networkName}/InitialProxy.json`).deployTxnHash; + const tx = await provider.getTransactionReceipt(deployTx); + networks[graphNetworkName].PerpsMarketProxy.startBlock = tx.blockNumber; + + const prettierOptions = JSON.parse(fs.readFileSync('../../../.prettierrc', 'utf8')); + + const pretty = prettier.format(JSON.stringify(networks, null, 2), { + parser: 'json', + ...prettierOptions, + }); + + fs.writeFileSync('./networks.json', pretty, 'utf8'); +} + +run(); diff --git a/markets/perps-market/subgraph/generated/PerpsMarket/PerpsMarketProxy.ts b/markets/perps-market/subgraph/generated/PerpsMarketProxy/PerpsMarketProxy.ts similarity index 95% rename from markets/perps-market/subgraph/generated/PerpsMarket/PerpsMarketProxy.ts rename to markets/perps-market/subgraph/generated/PerpsMarketProxy/PerpsMarketProxy.ts index 8eee9c19f2..f998670a3f 100644 --- a/markets/perps-market/subgraph/generated/PerpsMarket/PerpsMarketProxy.ts +++ b/markets/perps-market/subgraph/generated/PerpsMarketProxy/PerpsMarketProxy.ts @@ -394,6 +394,44 @@ export class OrderCommitted__Params { } } +export class MarketUpdated extends ethereum.Event { + get params(): MarketUpdated__Params { + return new MarketUpdated__Params(this); + } +} + +export class MarketUpdated__Params { + _event: MarketUpdated; + + constructor(event: MarketUpdated) { + this._event = event; + } + + get marketId(): BigInt { + return this._event.parameters[0].value.toBigInt(); + } + + get skew(): BigInt { + return this._event.parameters[1].value.toBigInt(); + } + + get size(): BigInt { + return this._event.parameters[2].value.toBigInt(); + } + + get sizeDelta(): BigInt { + return this._event.parameters[3].value.toBigInt(); + } + + get currentFundingRate(): BigInt { + return this._event.parameters[4].value.toBigInt(); + } + + get currentFundingVelocity(): BigInt { + return this._event.parameters[5].value.toBigInt(); + } +} + export class OrderSettled extends ethereum.Event { get params(): OrderSettled__Params { return new OrderSettled__Params(this); @@ -419,7 +457,7 @@ export class OrderSettled__Params { return this._event.parameters[2].value.toBigInt(); } - get accountPnlRealized(): BigInt { + get sizeDelta(): BigInt { return this._event.parameters[3].value.toBigInt(); } @@ -431,7 +469,7 @@ export class OrderSettled__Params { return this._event.parameters[5].value.toBigInt(); } - get settelementReward(): BigInt { + get settlementReward(): BigInt { return this._event.parameters[6].value.toBigInt(); } @@ -597,11 +635,11 @@ export class LiquidationParametersSet__Params { return this._event.parameters[0].value.toBigInt(); } - get initialMarginFraction(): BigInt { + get initialMarginRatioD18(): BigInt { return this._event.parameters[1].value.toBigInt(); } - get maintenanceMarginFraction(): BigInt { + get maintenanceMarginRatioD18(): BigInt { return this._event.parameters[2].value.toBigInt(); } @@ -616,18 +654,22 @@ export class LiquidationParametersSet__Params { get maxSecondsInLiquidationWindow(): BigInt { return this._event.parameters[5].value.toBigInt(); } + + get minimumPositionMargin(): BigInt { + return this._event.parameters[6].value.toBigInt(); + } } -export class LockedOiPercentSet extends ethereum.Event { - get params(): LockedOiPercentSet__Params { - return new LockedOiPercentSet__Params(this); +export class LockedOiRatioD18Set extends ethereum.Event { + get params(): LockedOiRatioD18Set__Params { + return new LockedOiRatioD18Set__Params(this); } } -export class LockedOiPercentSet__Params { - _event: LockedOiPercentSet; +export class LockedOiRatioD18Set__Params { + _event: LockedOiRatioD18Set; - constructor(event: LockedOiPercentSet) { + constructor(event: LockedOiRatioD18Set) { this._event = event; } @@ -635,21 +677,21 @@ export class LockedOiPercentSet__Params { return this._event.parameters[0].value.toBigInt(); } - get lockedOiPercent(): BigInt { + get lockedOiRatioD18(): BigInt { return this._event.parameters[1].value.toBigInt(); } } -export class MaxMarketValueSet extends ethereum.Event { - get params(): MaxMarketValueSet__Params { - return new MaxMarketValueSet__Params(this); +export class MaxMarketSizeSet extends ethereum.Event { + get params(): MaxMarketSizeSet__Params { + return new MaxMarketSizeSet__Params(this); } } -export class MaxMarketValueSet__Params { - _event: MaxMarketValueSet; +export class MaxMarketSizeSet__Params { + _event: MaxMarketSizeSet; - constructor(event: MaxMarketValueSet) { + constructor(event: MaxMarketSizeSet) { this._event = event; } @@ -657,7 +699,7 @@ export class MaxMarketValueSet__Params { return this._event.parameters[0].value.toBigInt(); } - get maxMarketValue(): BigInt { + get maxMarketSize(): BigInt { return this._event.parameters[1].value.toBigInt(); } } @@ -881,36 +923,6 @@ export class PerpsMarketProxy__getAssociatedSystemResult { } } -export class PerpsMarketProxy__getAsyncOrderClaimResultValue0Struct extends ethereum.Tuple { - get accountId(): BigInt { - return this[0].toBigInt(); - } - - get marketId(): BigInt { - return this[1].toBigInt(); - } - - get sizeDelta(): BigInt { - return this[2].toBigInt(); - } - - get settlementStrategyId(): BigInt { - return this[3].toBigInt(); - } - - get settlementTime(): BigInt { - return this[4].toBigInt(); - } - - get acceptablePrice(): BigInt { - return this[5].toBigInt(); - } - - get trackingCode(): Bytes { - return this[6].toBytes(); - } -} - export class PerpsMarketProxy__getOpenPositionResult { value0: BigInt; value1: BigInt; @@ -1172,11 +1184,11 @@ export class PerpsMarketProxy__getLiquidationParametersResult { return map; } - getInitialMarginFraction(): BigInt { + getInitialMarginRatioD18(): BigInt { return this.value0; } - getMaintenanceMarginFraction(): BigInt { + getMaintenanceMarginRatioD18(): BigInt { return this.value1; } @@ -1661,49 +1673,47 @@ export class PerpsMarketProxy extends ethereum.SmartContract { return ethereum.CallResult.fromValue(value[0].toString()); } - getAsyncOrderClaim( - accountId: BigInt, - marketId: BigInt - ): PerpsMarketProxy__getAsyncOrderClaimResultValue0Struct { - let result = super.call( - 'getAsyncOrderClaim', - 'getAsyncOrderClaim(uint128,uint128):((uint128,uint128,int128,uint128,uint256,uint256,bytes32))', - [ethereum.Value.fromUnsignedBigInt(accountId), ethereum.Value.fromUnsignedBigInt(marketId)] - ); + getAvailableMargin(accountId: BigInt): BigInt { + let result = super.call('getAvailableMargin', 'getAvailableMargin(uint128):(int256)', [ + ethereum.Value.fromUnsignedBigInt(accountId), + ]); - return changetype(result[0].toTuple()); + return result[0].toBigInt(); } - try_getAsyncOrderClaim( - accountId: BigInt, - marketId: BigInt - ): ethereum.CallResult { - let result = super.tryCall( - 'getAsyncOrderClaim', - 'getAsyncOrderClaim(uint128,uint128):((uint128,uint128,int128,uint128,uint256,uint256,bytes32))', - [ethereum.Value.fromUnsignedBigInt(accountId), ethereum.Value.fromUnsignedBigInt(marketId)] - ); + try_getAvailableMargin(accountId: BigInt): ethereum.CallResult { + let result = super.tryCall('getAvailableMargin', 'getAvailableMargin(uint128):(int256)', [ + ethereum.Value.fromUnsignedBigInt(accountId), + ]); if (result.reverted) { return new ethereum.CallResult(); } let value = result.value; - return ethereum.CallResult.fromValue( - changetype(value[0].toTuple()) - ); + return ethereum.CallResult.fromValue(value[0].toBigInt()); } - getAvailableMargin(accountId: BigInt): BigInt { - let result = super.call('getAvailableMargin', 'getAvailableMargin(uint128):(int256)', [ - ethereum.Value.fromUnsignedBigInt(accountId), - ]); + getCollateralAmount(accountId: BigInt, synthMarketId: BigInt): BigInt { + let result = super.call( + 'getCollateralAmount', + 'getCollateralAmount(uint128,uint128):(uint256)', + [ + ethereum.Value.fromUnsignedBigInt(accountId), + ethereum.Value.fromUnsignedBigInt(synthMarketId), + ] + ); return result[0].toBigInt(); } - try_getAvailableMargin(accountId: BigInt): ethereum.CallResult { - let result = super.tryCall('getAvailableMargin', 'getAvailableMargin(uint128):(int256)', [ - ethereum.Value.fromUnsignedBigInt(accountId), - ]); + try_getCollateralAmount(accountId: BigInt, synthMarketId: BigInt): ethereum.CallResult { + let result = super.tryCall( + 'getCollateralAmount', + 'getCollateralAmount(uint128,uint128):(uint256)', + [ + ethereum.Value.fromUnsignedBigInt(accountId), + ethereum.Value.fromUnsignedBigInt(synthMarketId), + ] + ); if (result.reverted) { return new ethereum.CallResult(); } @@ -1955,21 +1965,6 @@ export class PerpsMarketProxy extends ethereum.SmartContract { return ethereum.CallResult.fromValue(value[0].toBigInt()); } - PRECISION(): BigInt { - let result = super.call('PRECISION', 'PRECISION():(int256)', []); - - return result[0].toBigInt(); - } - - try_PRECISION(): ethereum.CallResult { - let result = super.tryCall('PRECISION', 'PRECISION():(int256)', []); - if (result.reverted) { - return new ethereum.CallResult(); - } - let value = result.value; - return ethereum.CallResult.fromValue(value[0].toBigInt()); - } - commitOrder( commitment: PerpsMarketProxy__commitOrderInputCommitmentStruct ): PerpsMarketProxy__commitOrderResult { @@ -2037,6 +2032,21 @@ export class PerpsMarketProxy extends ethereum.SmartContract { ); } + PRECISION(): BigInt { + let result = super.call('PRECISION', 'PRECISION():(int256)', []); + + return result[0].toBigInt(); + } + + try_PRECISION(): ethereum.CallResult { + let result = super.tryCall('PRECISION', 'PRECISION():(int256)', []); + if (result.reverted) { + return new ethereum.CallResult(); + } + let value = result.value; + return ethereum.CallResult.fromValue(value[0].toBigInt()); + } + getDeniers(feature: Bytes): Array

{ let result = super.call('getDeniers', 'getDeniers(bytes32):(address[])', [ ethereum.Value.fromFixedBytes(feature), @@ -2236,16 +2246,16 @@ export class PerpsMarketProxy extends ethereum.SmartContract { ); } - getLockedOiPercent(marketId: BigInt): BigInt { - let result = super.call('getLockedOiPercent', 'getLockedOiPercent(uint128):(uint256)', [ + getLockedOiRatioD18(marketId: BigInt): BigInt { + let result = super.call('getLockedOiRatioD18', 'getLockedOiRatioD18(uint128):(uint256)', [ ethereum.Value.fromUnsignedBigInt(marketId), ]); return result[0].toBigInt(); } - try_getLockedOiPercent(marketId: BigInt): ethereum.CallResult { - let result = super.tryCall('getLockedOiPercent', 'getLockedOiPercent(uint128):(uint256)', [ + try_getLockedOiRatioD18(marketId: BigInt): ethereum.CallResult { + let result = super.tryCall('getLockedOiRatioD18', 'getLockedOiRatioD18(uint128):(uint256)', [ ethereum.Value.fromUnsignedBigInt(marketId), ]); if (result.reverted) { @@ -2255,16 +2265,16 @@ export class PerpsMarketProxy extends ethereum.SmartContract { return ethereum.CallResult.fromValue(value[0].toBigInt()); } - getMaxMarketValue(marketId: BigInt): BigInt { - let result = super.call('getMaxMarketValue', 'getMaxMarketValue(uint128):(uint256)', [ + getMaxMarketSize(marketId: BigInt): BigInt { + let result = super.call('getMaxMarketSize', 'getMaxMarketSize(uint128):(uint256)', [ ethereum.Value.fromUnsignedBigInt(marketId), ]); return result[0].toBigInt(); } - try_getMaxMarketValue(marketId: BigInt): ethereum.CallResult { - let result = super.tryCall('getMaxMarketValue', 'getMaxMarketValue(uint128):(uint256)', [ + try_getMaxMarketSize(marketId: BigInt): ethereum.CallResult { + let result = super.tryCall('getMaxMarketSize', 'getMaxMarketSize(uint128):(uint256)', [ ethereum.Value.fromUnsignedBigInt(marketId), ]); if (result.reverted) { @@ -3645,11 +3655,11 @@ export class SetLiquidationParametersCall__Inputs { return this._call.inputValues[0].value.toBigInt(); } - get initialMarginFraction(): BigInt { + get initialMarginRatioD18(): BigInt { return this._call.inputValues[1].value.toBigInt(); } - get maintenanceMarginFraction(): BigInt { + get maintenanceMarginRatioD18(): BigInt { return this._call.inputValues[2].value.toBigInt(); } @@ -3664,6 +3674,10 @@ export class SetLiquidationParametersCall__Inputs { get maxSecondsInLiquidationWindow(): BigInt { return this._call.inputValues[5].value.toBigInt(); } + + get minimumPositionMargin(): BigInt { + return this._call.inputValues[6].value.toBigInt(); + } } export class SetLiquidationParametersCall__Outputs { @@ -3674,20 +3688,20 @@ export class SetLiquidationParametersCall__Outputs { } } -export class SetLockedOiPercentCall extends ethereum.Call { - get inputs(): SetLockedOiPercentCall__Inputs { - return new SetLockedOiPercentCall__Inputs(this); +export class SetLockedOiRatioCall extends ethereum.Call { + get inputs(): SetLockedOiRatioCall__Inputs { + return new SetLockedOiRatioCall__Inputs(this); } - get outputs(): SetLockedOiPercentCall__Outputs { - return new SetLockedOiPercentCall__Outputs(this); + get outputs(): SetLockedOiRatioCall__Outputs { + return new SetLockedOiRatioCall__Outputs(this); } } -export class SetLockedOiPercentCall__Inputs { - _call: SetLockedOiPercentCall; +export class SetLockedOiRatioCall__Inputs { + _call: SetLockedOiRatioCall; - constructor(call: SetLockedOiPercentCall) { + constructor(call: SetLockedOiRatioCall) { this._call = call; } @@ -3695,33 +3709,33 @@ export class SetLockedOiPercentCall__Inputs { return this._call.inputValues[0].value.toBigInt(); } - get lockedOiPercent(): BigInt { + get lockedOiRatioD18(): BigInt { return this._call.inputValues[1].value.toBigInt(); } } -export class SetLockedOiPercentCall__Outputs { - _call: SetLockedOiPercentCall; +export class SetLockedOiRatioCall__Outputs { + _call: SetLockedOiRatioCall; - constructor(call: SetLockedOiPercentCall) { + constructor(call: SetLockedOiRatioCall) { this._call = call; } } -export class SetMaxMarketValueCall extends ethereum.Call { - get inputs(): SetMaxMarketValueCall__Inputs { - return new SetMaxMarketValueCall__Inputs(this); +export class SetMaxMarketSizeCall extends ethereum.Call { + get inputs(): SetMaxMarketSizeCall__Inputs { + return new SetMaxMarketSizeCall__Inputs(this); } - get outputs(): SetMaxMarketValueCall__Outputs { - return new SetMaxMarketValueCall__Outputs(this); + get outputs(): SetMaxMarketSizeCall__Outputs { + return new SetMaxMarketSizeCall__Outputs(this); } } -export class SetMaxMarketValueCall__Inputs { - _call: SetMaxMarketValueCall; +export class SetMaxMarketSizeCall__Inputs { + _call: SetMaxMarketSizeCall; - constructor(call: SetMaxMarketValueCall) { + constructor(call: SetMaxMarketSizeCall) { this._call = call; } @@ -3729,15 +3743,15 @@ export class SetMaxMarketValueCall__Inputs { return this._call.inputValues[0].value.toBigInt(); } - get maxMarketValue(): BigInt { + get maxMarketSize(): BigInt { return this._call.inputValues[1].value.toBigInt(); } } -export class SetMaxMarketValueCall__Outputs { - _call: SetMaxMarketValueCall; +export class SetMaxMarketSizeCall__Outputs { + _call: SetMaxMarketSizeCall; - constructor(call: SetMaxMarketValueCall) { + constructor(call: SetMaxMarketSizeCall) { this._call = call; } } diff --git a/markets/perps-market/subgraph/networks.json b/markets/perps-market/subgraph/networks.json index e6ee6e379d..ce0e262f12 100644 --- a/markets/perps-market/subgraph/networks.json +++ b/markets/perps-market/subgraph/networks.json @@ -1,8 +1,8 @@ { "optimism-goerli": { - "PerpsMarket": { - "address": "0x54D71285871C5a0914F5B53740b70bA3eDb51Fbb", - "startBlock": 9727531 + "PerpsMarketProxy": { + "address": "0xd78D47739Ed468a602beb11C34a2A20759bcEf4F", + "startBlock": 11669270 } } } diff --git a/markets/perps-market/subgraph/package.json b/markets/perps-market/subgraph/package.json index 7558d46413..ac62e26eb9 100644 --- a/markets/perps-market/subgraph/package.json +++ b/markets/perps-market/subgraph/package.json @@ -4,14 +4,19 @@ "private": true, "version": "1.0.0", "scripts": { - "subgraphgen": "yarn prepare && graph codegen && prettier --write . && yarn codegen", - "build": "yarn build:optimism-goerli", + "subgraphgen": "yarn deployments:optimism-goerli && yarn codegen", + "deployments": "yarn deployments:optimism-mainnet && yarn deployments:optimism-goerli", "auth": "graph auth --product hosted-service $V3_GRAPH_KEY", + "deployments:optimism-mainnet": "echo SKIP || cannon inspect synthetix-perps-market:latest --chain-id 10 --write-deployments ./deployments/optimism-mainnet", + "deployments:optimism-goerli": "cannon inspect synthetix-perps-market:latest --chain-id 420 --write-deployments ./deployments/optimism-goerli", "prepare": "cp ./subgraph.base.yaml ./subgraph.yaml", "codegen": "yarn prepare && graph codegen && prettier --write .", - "build:optimism-goerli": "yarn codegen && graph build --output-dir ./build/optimism-goerli --network optimism-goerli", + "build:optimism-mainnet": "echo SKIP || node ./codegen optimism-mainnet && yarn codegen && graph build --output-dir ./build/optimism-mainnet --network optimism", + "deploy:optimism-mainnet": "echo SKIP || graph deploy --output-dir ./build/optimism-mainnet --network optimism --product hosted-service snx-v3/perps-market-optimism-mainnet", + "build:optimism-goerli": "node ./codegen optimism-goerli && yarn codegen && graph build --output-dir ./build/optimism-goerli --network optimism-goerli", "deploy:optimism-goerli": "graph deploy --output-dir ./build/optimism-goerli --network optimism-goerli --product hosted-service snx-v3/perps-market-optimism-goerli", - "test": "yarn prepare && graph test", + "test": "echo 'SKIP: No tests' || graph test", + "coverage": "yarn deployments:optimism-goerli && yarn codegen && git diff --exit-code && yarn test", "create-local": "graph create --node http://localhost:8020/ snx-v3/goerli", "remove-local": "graph remove --node http://localhost:8020/ snx-v3/goerli", "deploy-local": "graph deploy --node http://localhost:8020/ --ipfs http://localhost:5001 snx-v3/goerli" @@ -19,6 +24,8 @@ "devDependencies": { "@graphprotocol/graph-cli": "^0.50.1", "@graphprotocol/graph-ts": "^0.30.0", + "@usecannon/cli": "^2.4.20", + "ethers": "^5.7.2", "prettier": "^2.8.8" } } diff --git a/markets/perps-market/subgraph/src/account.ts b/markets/perps-market/subgraph/src/account.ts index cdca813783..bb62e819a6 100644 --- a/markets/perps-market/subgraph/src/account.ts +++ b/markets/perps-market/subgraph/src/account.ts @@ -1,4 +1,4 @@ -import { AccountCreated } from '../generated/PerpsMarket/PerpsMarketProxy'; +import { AccountCreated } from '../generated/PerpsMarketProxy/PerpsMarketProxy'; import { Account } from '../generated/schema'; diff --git a/markets/perps-market/subgraph/src/market.ts b/markets/perps-market/subgraph/src/market.ts index dda4335f30..c3c885742e 100644 --- a/markets/perps-market/subgraph/src/market.ts +++ b/markets/perps-market/subgraph/src/market.ts @@ -4,9 +4,9 @@ import { MarketRegistered, FundingParametersSet, LiquidationParametersSet, - LockedOiPercentSet, + LockedOiRatioD18Set, OrderFeesSet, -} from '../generated/PerpsMarket/PerpsMarketProxy'; +} from '../generated/PerpsMarketProxy/PerpsMarketProxy'; import { Market } from '../generated/schema'; @@ -52,12 +52,12 @@ export function handleFundingParametersSet(event: FundingParametersSet): void { } } -export function handleLockedOiPercentSet(event: LockedOiPercentSet): void { +export function handleLockedOiRatioD18Set(event: LockedOiRatioD18Set): void { const id = event.params.marketId.toString(); const market = Market.load(id); if (market) { - market.lockedOiPercent = event.params.lockedOiPercent; + market.lockedOiPercent = event.params.lockedOiRatioD18; market.save(); } } @@ -67,9 +67,9 @@ export function handleLiquidationParametersSet(event: LiquidationParametersSet): const market = Market.load(id); if (market) { - market.initialMarginFraction = event.params.initialMarginFraction; + market.initialMarginFraction = event.params.initialMarginRatioD18; market.liquidationRewardRatioD18 = event.params.liquidationRewardRatioD18; - market.maintenanceMarginFraction = event.params.maintenanceMarginFraction; + market.maintenanceMarginFraction = event.params.maintenanceMarginRatioD18; market.maxLiquidationLimitAccumulationMultiplier = event.params.maxLiquidationLimitAccumulationMultiplier; market.save(); diff --git a/markets/perps-market/subgraph/src/orders.ts b/markets/perps-market/subgraph/src/orders.ts index 1dd87f0713..7c2aa95c04 100644 --- a/markets/perps-market/subgraph/src/orders.ts +++ b/markets/perps-market/subgraph/src/orders.ts @@ -1,4 +1,4 @@ -import { OrderCommitted } from '../generated/PerpsMarket/PerpsMarketProxy'; +import { OrderCommitted } from '../generated/PerpsMarketProxy/PerpsMarketProxy'; import { BigInt } from '@graphprotocol/graph-ts'; import { ZERO_BI } from './helpers'; import { Order } from '../generated/schema'; diff --git a/markets/perps-market/subgraph/src/settlementStrategies.ts b/markets/perps-market/subgraph/src/settlementStrategies.ts index 7d30110072..6a0a51011b 100644 --- a/markets/perps-market/subgraph/src/settlementStrategies.ts +++ b/markets/perps-market/subgraph/src/settlementStrategies.ts @@ -1,7 +1,7 @@ import { SettlementStrategyAdded, SettlementStrategyEnabled, -} from '../generated/PerpsMarket/PerpsMarketProxy'; +} from '../generated/PerpsMarketProxy/PerpsMarketProxy'; import { SettlementStrategy } from '../generated/schema'; diff --git a/markets/perps-market/subgraph/subgraph.base.yaml b/markets/perps-market/subgraph/subgraph.base.yaml index b007bc266c..9b0ea31e9e 100644 --- a/markets/perps-market/subgraph/subgraph.base.yaml +++ b/markets/perps-market/subgraph/subgraph.base.yaml @@ -3,7 +3,7 @@ schema: file: ./schema.graphql dataSources: - kind: ethereum - name: PerpsMarket + name: PerpsMarketProxy source: abi: PerpsMarketProxy mapping: @@ -12,7 +12,7 @@ dataSources: language: wasm/assemblyscript abis: - name: PerpsMarketProxy - file: ./abis/PerpsMarketProxy.json + file: ./deployments/optimism-goerli/PerpsMarketProxy.json entities: - Account - Market @@ -25,19 +25,19 @@ dataSources: handler: handleMarketRegistered - event: MarketPriceDataUpdated(indexed uint128,bytes32) handler: handleMarketPriceDataUpdated - - event: FundingParametersSet(uint128,uint256,uint256) + - event: FundingParametersSet(indexed uint128,uint256,uint256) handler: handleFundingParametersSet - - event: LiquidationParametersSet(uint128,uint256,uint256,uint256,uint256,uint256) + - event: LiquidationParametersSet(indexed uint128,uint256,uint256,uint256,uint256,uint256,uint256) handler: handleLiquidationParametersSet - - event: LockedOiPercentSet(uint128,uint256) - handler: handleLockedOiPercentSet - - event: OrderFeesSet(uint128,uint256,uint256) + - event: LockedOiRatioD18Set(indexed uint128,uint256) + handler: handleLockedOiRatioD18Set + - event: OrderFeesSet(indexed uint128,uint256,uint256) handler: handleOrderFeesSet - event: SettlementStrategyAdded(indexed uint128,(uint8,uint256,uint256,uint256,address,bytes32,string,uint256,uint256,bool),indexed uint256) handler: handleSettlementStrategyAdded - - event: SettlementStrategyEnabled(uint128,uint256,bool) + - event: SettlementStrategyEnabled(indexed uint128,uint256,bool) handler: handleSettlementStrategyEnabled - - event: OrderCommitted(indexed uint128,indexed uint128,indexed uint8,int128,uint256,uint256,uint256,bytes32,address) + - event: OrderCommitted(indexed uint128,indexed uint128,uint8,int128,uint256,uint256,uint256,indexed bytes32,address) handler: handleOrderCommitted file: ./src/core.ts diff --git a/yarn.lock b/yarn.lock index 333ec30937..40c4ed9518 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2838,6 +2838,8 @@ __metadata: dependencies: "@graphprotocol/graph-cli": ^0.50.1 "@graphprotocol/graph-ts": ^0.30.0 + "@usecannon/cli": ^2.4.20 + ethers: ^5.7.2 prettier: ^2.8.8 languageName: unknown linkType: soft From 8a360c898e0b3a3671924d64de132c5e4ab05f63 Mon Sep 17 00:00:00 2001 From: "troy (troyb.eth)" Date: Thu, 13 Jul 2023 15:11:37 -0600 Subject: [PATCH 04/63] update docs link in readme (#1715) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c10eae42ca..14fc089b4b 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ ## Documentation -Please refer to the [Official Documentation](https://snx-v3-docs.vercel.app/) for high level concepts of the Synthetix v3 protocol, as well as auto generated docs from natspec. +Please refer to the [Official Documentation](https://docs.synthetix.io/) for high level concepts of the Synthetix v3 protocol, as well as auto generated docs from natspec. ## Package structure From a27b621b4c687363c155a63d108a18fdb10b1eca Mon Sep 17 00:00:00 2001 From: Peiman Date: Fri, 14 Jul 2023 11:34:02 +0330 Subject: [PATCH 05/63] fix: resolve PR comments --- .../synthetix/contracts/interfaces/IPoolModule.sol | 4 ++-- .../contracts/modules/core/IssueUSDModule.sol | 3 +-- .../synthetix/contracts/modules/core/PoolModule.sol | 10 +++++----- protocol/synthetix/contracts/storage/Pool.sol | 4 ++-- protocol/synthetix/storage.dump.sol | 4 ++-- .../integration/modules/core/IssueUSDModule.test.ts | 2 +- .../modules/core/PoolModuleFundAdmin.test.ts | 10 +++++----- 7 files changed, 18 insertions(+), 19 deletions(-) diff --git a/protocol/synthetix/contracts/interfaces/IPoolModule.sol b/protocol/synthetix/contracts/interfaces/IPoolModule.sol index 3b07d1273c..360163fb93 100644 --- a/protocol/synthetix/contracts/interfaces/IPoolModule.sol +++ b/protocol/synthetix/contracts/interfaces/IPoolModule.sol @@ -217,7 +217,7 @@ interface IPoolModule { * @param collateral The address of the collateral. * @param issuanceRatioD18 The minimum issuance ratio denominated with 18 decimal places */ - function setPoolCollateralIssuanceRatioD18( + function setPoolCollateralIssuanceRatio( uint128 poolId, address collateral, uint256 issuanceRatioD18 @@ -228,7 +228,7 @@ interface IPoolModule { * @param poolId The id of the pool for to check the collateral for. * @param collateral The address of the collateral. */ - function getPoolCollateralIssuanceRatioD18( + function getPoolCollateralIssuanceRatio( uint128 poolId, address collateral ) external returns (uint256 issuanceRatioD18); diff --git a/protocol/synthetix/contracts/modules/core/IssueUSDModule.sol b/protocol/synthetix/contracts/modules/core/IssueUSDModule.sol index 5c8aedb45b..963cd28099 100644 --- a/protocol/synthetix/contracts/modules/core/IssueUSDModule.sol +++ b/protocol/synthetix/contracts/modules/core/IssueUSDModule.sol @@ -84,11 +84,10 @@ contract IssueUSDModule is IIssueUSDModule { // If the resulting debt of the account is greater than zero, ensure that the resulting c-ratio is sufficient (, uint256 collateralValue) = pool.currentAccountCollateral(collateralType, accountId); if (newDebt > 0) { - uint256 minIssuanceRatioD18 = pool.issuanceRatioD18[collateralType]; CollateralConfiguration.load(collateralType).verifyIssuanceRatio( newDebt.toUint(), collateralValue, - minIssuanceRatioD18 + pool.issuanceRatioD18[collateralType] ); } diff --git a/protocol/synthetix/contracts/modules/core/PoolModule.sol b/protocol/synthetix/contracts/modules/core/PoolModule.sol index 59c3b46eb6..e7f1ce99fb 100644 --- a/protocol/synthetix/contracts/modules/core/PoolModule.sol +++ b/protocol/synthetix/contracts/modules/core/PoolModule.sol @@ -235,7 +235,7 @@ contract PoolModule is IPoolModule { Pool.Data storage pool = Pool.loadExisting(poolId); Pool.onlyPoolOwner(poolId, msg.sender); - pool.disabledCollaterals[collateral] = false; + pool.collateralTypeDisabled[collateral] = false; emit PoolCollateralEnabled(poolId, collateral, msg.sender); } @@ -247,7 +247,7 @@ contract PoolModule is IPoolModule { Pool.Data storage pool = Pool.loadExisting(poolId); Pool.onlyPoolOwner(poolId, msg.sender); - pool.disabledCollaterals[collateral] = true; + pool.collateralTypeDisabled[collateral] = true; emit PoolCollateralDisabled(poolId, collateral, msg.sender); } @@ -259,13 +259,13 @@ contract PoolModule is IPoolModule { uint128 poolId, address collateral ) external view override returns (bool) { - return !Pool.load(poolId).disabledCollaterals[collateral]; + return !Pool.load(poolId).collateralTypeDisabled[collateral]; } /** * @inheritdoc IPoolModule */ - function setPoolCollateralIssuanceRatioD18( + function setPoolCollateralIssuanceRatio( uint128 poolId, address collateral, uint256 issuanceRatioD18 @@ -281,7 +281,7 @@ contract PoolModule is IPoolModule { /** * @inheritdoc IPoolModule */ - function getPoolCollateralIssuanceRatioD18( + function getPoolCollateralIssuanceRatio( uint128 poolId, address collateral ) external view override returns (uint256) { diff --git a/protocol/synthetix/contracts/storage/Pool.sol b/protocol/synthetix/contracts/storage/Pool.sol index efb1233a10..8552ac783a 100644 --- a/protocol/synthetix/contracts/storage/Pool.sol +++ b/protocol/synthetix/contracts/storage/Pool.sol @@ -118,7 +118,7 @@ library Pool { uint64 __reserved1; uint64 __reserved2; uint64 __reserved3; - mapping(address => bool) disabledCollaterals; + mapping(address => bool) collateralTypeDisabled; mapping(address => uint256) issuanceRatioD18; } @@ -520,7 +520,7 @@ library Pool { * @param collateral The address of the collateral. */ function checkDelegationEnabled(Data storage self, address collateral) internal view { - if (self.disabledCollaterals[collateral]) { + if (self.collateralTypeDisabled[collateral]) { revert PoolCollateralIsDisabled(collateral, self.id); } } diff --git a/protocol/synthetix/storage.dump.sol b/protocol/synthetix/storage.dump.sol index 0ed4e7e401..a0061373fe 100644 --- a/protocol/synthetix/storage.dump.sol +++ b/protocol/synthetix/storage.dump.sol @@ -544,8 +544,8 @@ library Pool { uint64 __reserved1; uint64 __reserved2; uint64 __reserved3; - mapping(address => bool) disabledCollaterals; - mapping(address => uint256) IssuanceRatio; + mapping(address => bool) collateralTypeDisabled; + mapping(address => uint256) issuanceRatioD18; } function load(uint128 id) internal pure returns (Data storage pool) { bytes32 s = keccak256(abi.encode("io.synthetix.synthetix.Pool", id)); diff --git a/protocol/synthetix/test/integration/modules/core/IssueUSDModule.test.ts b/protocol/synthetix/test/integration/modules/core/IssueUSDModule.test.ts index 7b20b2ceec..0d47b46ec3 100644 --- a/protocol/synthetix/test/integration/modules/core/IssueUSDModule.test.ts +++ b/protocol/synthetix/test/integration/modules/core/IssueUSDModule.test.ts @@ -450,7 +450,7 @@ describe('IssueUSDModule', function () { it('set the pool min collateal issuance ratio to 600%', async () => { await systems() .Core.connect(owner) - .setPoolCollateralIssuanceRatioD18(poolId, collateralAddress(), bn(6)); + .setPoolCollateralIssuanceRatio(poolId, collateralAddress(), bn(6)); }); it('verifies sufficient c-ratio', async () => { diff --git a/protocol/synthetix/test/integration/modules/core/PoolModuleFundAdmin.test.ts b/protocol/synthetix/test/integration/modules/core/PoolModuleFundAdmin.test.ts index d633261d4d..42290551aa 100644 --- a/protocol/synthetix/test/integration/modules/core/PoolModuleFundAdmin.test.ts +++ b/protocol/synthetix/test/integration/modules/core/PoolModuleFundAdmin.test.ts @@ -736,7 +736,7 @@ describe('PoolModule Admin', function () { }); }); - describe('setPoolCollateralIssuanceRatioD18()', async () => { + describe('setPoolCollateralIssuanceRatio()', async () => { before(restore); before('give user1 permission to create pool', async () => { @@ -760,7 +760,7 @@ describe('PoolModule Admin', function () { await assertRevert( systems() .Core.connect(user2) - .setPoolCollateralIssuanceRatioD18(thirdPoolId, collateralAddress(), bn(2)), + .setPoolCollateralIssuanceRatio(thirdPoolId, collateralAddress(), bn(2)), `Unauthorized("${await user2.getAddress()}")`, systems().Core ); @@ -768,7 +768,7 @@ describe('PoolModule Admin', function () { it('min collateral ratio is set to zero for the pool by default', async () => { await assert.equal( - await systems().Core.getPoolCollateralIssuanceRatioD18(thirdPoolId, collateralAddress()), + await systems().Core.getPoolCollateralIssuanceRatio(thirdPoolId, collateralAddress()), 0 ); }); @@ -776,10 +776,10 @@ describe('PoolModule Admin', function () { it('set the pool collateal issuance ratio to 200%', async () => { await systems() .Core.connect(user1) - .setPoolCollateralIssuanceRatioD18(thirdPoolId, collateralAddress(), bn(2)); + .setPoolCollateralIssuanceRatio(thirdPoolId, collateralAddress(), bn(2)); await assertBn.equal( - await systems().Core.getPoolCollateralIssuanceRatioD18(thirdPoolId, collateralAddress()), + await systems().Core.getPoolCollateralIssuanceRatio(thirdPoolId, collateralAddress()), bn(2) ); }); From 0679c45b3862fb6f074bd1c54552c55f6ba40e49 Mon Sep 17 00:00:00 2001 From: Sunny Vempati Date: Mon, 17 Jul 2023 06:08:22 -0500 Subject: [PATCH 06/63] accrued funding remove hard code (#1705) Co-authored-by: Leonardo Massazza --- .../test/integration/Position/Funding.test.ts | 128 ++++++++++++------ 1 file changed, 84 insertions(+), 44 deletions(-) diff --git a/markets/perps-market/test/integration/Position/Funding.test.ts b/markets/perps-market/test/integration/Position/Funding.test.ts index 486a3f8abe..e8734aba7f 100644 --- a/markets/perps-market/test/integration/Position/Funding.test.ts +++ b/markets/perps-market/test/integration/Position/Funding.test.ts @@ -1,9 +1,15 @@ import { DEFAULT_SETTLEMENT_STRATEGY, PerpsMarket, bn, bootstrapMarkets } from '../bootstrap'; import { openPosition } from '../helpers'; +import Wei, { wei } from '@synthetixio/wei'; import { fastForwardTo } from '@synthetixio/core-utils/utils/hardhat/rpc'; import assertBn from '@synthetixio/core-utils/utils/assertions/assert-bignumber'; -const SECONDS_IN_DAY = 24 * 60 * 60; +const _SECONDS_IN_DAY = 24 * 60 * 60; + +const _SKEW_SCALE = bn(10_000); +const _MAX_FUNDING_VELOCITY = bn(3); +const _TRADER_SIZE = bn(20); +const _ETH_PRICE = bn(2000); describe('Position - funding', () => { const { systems, perpsMarkets, provider, trader1, trader2, keeper } = bootstrapMarkets({ @@ -12,8 +18,8 @@ describe('Position - funding', () => { { name: 'Ether', token: 'snxETH', - price: bn(2000), - fundingParams: { skewScale: bn(10_000), maxFundingVelocity: bn(3) }, + price: _ETH_PRICE, + fundingParams: { skewScale: _SKEW_SCALE, maxFundingVelocity: bn(3) }, }, ], traderAccountIds: [2, 3], @@ -40,7 +46,7 @@ describe('Position - funding', () => { accountId: 2, keeper: keeper(), marketId: ethMarket.marketId(), - sizeDelta: bn(20), + sizeDelta: _TRADER_SIZE, settlementStrategyId: ethMarket.strategyId(), price: bn(2000), }); @@ -64,48 +70,82 @@ describe('Position - funding', () => { */ [ - { daysElapsed: 1, newOrderSize: bn(-60), expectedAccruedFunding: bn(-120) }, - { daysElapsed: 2, newOrderSize: bn(15), expectedAccruedFunding: bn(-120) }, - { daysElapsed: 2.25, newOrderSize: bn(37), expectedAccruedFunding: bn(-50.63) }, - { daysElapsed: 4.25, newOrderSize: bn(-17), expectedAccruedFunding: bn(291.38) }, - { daysElapsed: 4.45, newOrderSize: bn(155), expectedAccruedFunding: bn(297.98) }, - { daysElapsed: 4.55, newOrderSize: bn(-150), expectedAccruedFunding: bn(292.88) }, - { daysElapsed: 4.65, newOrderSize: bn(-15), expectedAccruedFunding: bn(278.78) }, - { daysElapsed: 4.68, newOrderSize: bn(-4), expectedAccruedFunding: bn(274.63) }, - { daysElapsed: 7.68, newOrderSize: bn(19), expectedAccruedFunding: bn(893.83) }, - ].forEach(({ daysElapsed, newOrderSize, expectedAccruedFunding }) => { - describe(`after ${daysElapsed} days`, () => { - before('move time', async () => { - await fastForwardTo( - openPositionTime - - // this enables the market summary check to be as close as possible to the settlement time - (DEFAULT_SETTLEMENT_STRATEGY.settlementDelay - 1) + // settlement strategy delay accounted for - SECONDS_IN_DAY * daysElapsed, - provider() - ); - }); + { daysElapsed: 1, newOrderSize: bn(-60) }, + { daysElapsed: 1, newOrderSize: bn(15) }, + { daysElapsed: 0.25, newOrderSize: bn(37) }, + { daysElapsed: 2, newOrderSize: bn(-17) }, + { daysElapsed: 0.2, newOrderSize: bn(155) }, + { daysElapsed: 0.1, newOrderSize: bn(-150) }, + { daysElapsed: 0.1, newOrderSize: bn(-15) }, + { daysElapsed: 0.03, newOrderSize: bn(-4) }, + { daysElapsed: 3, newOrderSize: bn(19) }, + ].reduce( + ( + { prevFrVelocity, prevFundingRate, prevAccruedFunding, prevSkew, accDaysElapsed }, + { daysElapsed, newOrderSize } + ) => { + accDaysElapsed += daysElapsed; + + // ACCRUED FUNDING CALC ---------------------------------------------- + const currentSkew = prevSkew.add(newOrderSize); + const frVelocity = wei(currentSkew).div(_SKEW_SCALE).mul(_MAX_FUNDING_VELOCITY); + const fundingRate = prevFrVelocity.mul(daysElapsed).add(prevFundingRate); + const expectedAccruedFunding = Wei.avg(wei(prevFundingRate), wei(fundingRate)) + .mul(_TRADER_SIZE) + .mul(_ETH_PRICE) + .mul(daysElapsed) + .add(prevAccruedFunding); + // END ACCRUED FUNDING CALC ------------------------------------------- - before('trader2 moves skew', async () => { - await openPosition({ - systems, - provider, - trader: trader2(), - accountId: 3, - keeper: trader2(), - marketId: ethMarket.marketId(), - sizeDelta: newOrderSize, - settlementStrategyId: ethMarket.strategyId(), - price: bn(2000), + describe(`after ${daysElapsed} days`, () => { + before('move time', async () => { + await fastForwardTo( + openPositionTime - + // this enables the market summary check to be as close as possible to the settlement time + (DEFAULT_SETTLEMENT_STRATEGY.settlementDelay - 1) + // settlement strategy delay accounted for + _SECONDS_IN_DAY * accDaysElapsed, + provider() + ); + }); + + before('trader2 moves skew', async () => { + await openPosition({ + systems, + provider, + trader: trader2(), + accountId: 3, + keeper: trader2(), + marketId: ethMarket.marketId(), + sizeDelta: newOrderSize, + settlementStrategyId: ethMarket.strategyId(), + price: bn(2000), + }); }); - }); - it('funding accrued is correct', async () => { - const [, accruedFunding] = await systems().PerpsMarket.getOpenPosition( - 2, - ethMarket.marketId() - ); - assertBn.near(accruedFunding, expectedAccruedFunding, bn(0.1)); + it('funding accrued is correct', async () => { + const [, accruedFunding] = await systems().PerpsMarket.getOpenPosition( + 2, + ethMarket.marketId() + ); + // using negative value because trader pnl + assertBn.near(accruedFunding, expectedAccruedFunding.mul(-1).toBN(), bn(0.1)); + }); }); - }); - }); + + return { + prevFrVelocity: frVelocity, + prevFundingRate: fundingRate, + prevAccruedFunding: expectedAccruedFunding, + prevSkew: currentSkew, + accDaysElapsed, + }; + }, + { + prevFrVelocity: wei(0.006), + prevFundingRate: wei(0), + prevAccruedFunding: wei(0), + prevSkew: wei(20), + accDaysElapsed: 0, + } + ); }); From 7e7143fdfec3a30827a9116f4d18f7268dc131a9 Mon Sep 17 00:00:00 2001 From: Leonardo Massazza Date: Mon, 17 Jul 2023 16:10:40 +0100 Subject: [PATCH 07/63] Clean lint warnings (#1712) --- markets/legacy-market/contracts/LegacyMarket.sol | 3 ++- .../contracts/interfaces/external/ISpotMarketSystem.sol | 5 ++++- .../contracts/interfaces/external/ISynthetixSystem.sol | 5 ++++- markets/perps-market/contracts/mocks/MockPyth.sol | 3 ++- .../contracts/interfaces/external/ISynthetixSystem.sol | 6 +++++- markets/spot-market/contracts/mocks/FeeCollectorMock.sol | 5 +++++ .../spot-market/contracts/mocks/OracleVerifierMock.sol | 8 ++++++++ .../contracts/modules/council-nft/CouncilTokenModule.sol | 1 + .../contracts/submodules/election/ElectionCredentials.sol | 2 +- protocol/oracle-manager/contracts/mocks/pyth/MockPyth.sol | 8 ++++---- .../contracts/interfaces/external/IOracleManager.sol | 1 + protocol/synthetix/contracts/mocks/CcipRouterMock.sol | 2 ++ protocol/synthetix/contracts/storage/Vault.sol | 1 + 13 files changed, 40 insertions(+), 10 deletions(-) diff --git a/markets/legacy-market/contracts/LegacyMarket.sol b/markets/legacy-market/contracts/LegacyMarket.sol index faf9689fe6..f52334c5f8 100644 --- a/markets/legacy-market/contracts/LegacyMarket.sol +++ b/markets/legacy-market/contracts/LegacyMarket.sol @@ -28,7 +28,7 @@ contract LegacyMarket is ILegacyMarket, Ownable, UUPSImplementation, IMarket { bool public pauseMigration; // used by _migrate to temporarily set reportedDebt to another value before - uint256 tmpLockedDebt; + uint256 internal tmpLockedDebt; IAddressResolver public v2xResolver; IV3CoreProxy public v3System; @@ -38,6 +38,7 @@ contract LegacyMarket is ILegacyMarket, Ownable, UUPSImplementation, IMarket { error InsufficientCollateralMigrated(uint256 amountRequested, uint256 amountAvailable); error Paused(); + // solhint-disable-next-line no-empty-blocks constructor() Ownable(msg.sender) {} /** diff --git a/markets/perps-market/contracts/interfaces/external/ISpotMarketSystem.sol b/markets/perps-market/contracts/interfaces/external/ISpotMarketSystem.sol index 882c8447b2..6f0589a6ce 100644 --- a/markets/perps-market/contracts/interfaces/external/ISpotMarketSystem.sol +++ b/markets/perps-market/contracts/interfaces/external/ISpotMarketSystem.sol @@ -4,4 +4,7 @@ pragma solidity >=0.8.11 <0.9.0; import {IAtomicOrderModule} from "@synthetixio/spot-market/contracts/interfaces/IAtomicOrderModule.sol"; import {ISpotMarketFactoryModule} from "@synthetixio/spot-market/contracts/interfaces/ISpotMarketFactoryModule.sol"; -interface ISpotMarketSystem is IAtomicOrderModule, ISpotMarketFactoryModule {} +// solhint-disable-next-line no-empty-blocks +interface ISpotMarketSystem is IAtomicOrderModule, ISpotMarketFactoryModule { + +} diff --git a/markets/perps-market/contracts/interfaces/external/ISynthetixSystem.sol b/markets/perps-market/contracts/interfaces/external/ISynthetixSystem.sol index 7812baf4c9..dbb26c9219 100644 --- a/markets/perps-market/contracts/interfaces/external/ISynthetixSystem.sol +++ b/markets/perps-market/contracts/interfaces/external/ISynthetixSystem.sol @@ -5,4 +5,7 @@ import {IAssociatedSystemsModule} from "@synthetixio/core-modules/contracts/inte import {IMarketManagerModule} from "@synthetixio/main/contracts/interfaces/IMarketManagerModule.sol"; import {IUtilsModule} from "@synthetixio/main/contracts/interfaces/IUtilsModule.sol"; -interface ISynthetixSystem is IAssociatedSystemsModule, IMarketManagerModule, IUtilsModule {} +// solhint-disable-next-line no-empty-blocks +interface ISynthetixSystem is IAssociatedSystemsModule, IMarketManagerModule, IUtilsModule { + +} diff --git a/markets/perps-market/contracts/mocks/MockPyth.sol b/markets/perps-market/contracts/mocks/MockPyth.sol index 1beb560d01..fcd59c605a 100644 --- a/markets/perps-market/contracts/mocks/MockPyth.sol +++ b/markets/perps-market/contracts/mocks/MockPyth.sol @@ -7,10 +7,11 @@ import {MockPyth as BaseMockPyth} from "@synthetixio/oracle-manager/contracts/mo * @title Module for connecting to other systems. * See oracle-manager/../MockPyth */ -// solhint-disable-next-line no-empty-blocks contract MockPyth is BaseMockPyth { + // solhint-disable no-empty-blocks constructor( uint _validTimePeriod, uint _singleUpdateFeeInWei ) BaseMockPyth(_validTimePeriod, _singleUpdateFeeInWei) {} + // solhint-enable no-empty-blocks } diff --git a/markets/spot-market/contracts/interfaces/external/ISynthetixSystem.sol b/markets/spot-market/contracts/interfaces/external/ISynthetixSystem.sol index d069d439dd..a833bccd92 100644 --- a/markets/spot-market/contracts/interfaces/external/ISynthetixSystem.sol +++ b/markets/spot-market/contracts/interfaces/external/ISynthetixSystem.sol @@ -6,9 +6,13 @@ import "@synthetixio/main/contracts/interfaces/IMarketManagerModule.sol"; import "@synthetixio/main/contracts/interfaces/IMarketCollateralModule.sol"; import "@synthetixio/main/contracts/interfaces/IUtilsModule.sol"; +// solhint-disable no-empty-blocks interface ISynthetixSystem is IAssociatedSystemsModule, IMarketCollateralModule, IMarketManagerModule, IUtilsModule -{} +{ + +} +// solhint-enable no-empty-blocks diff --git a/markets/spot-market/contracts/mocks/FeeCollectorMock.sol b/markets/spot-market/contracts/mocks/FeeCollectorMock.sol index 2d6b5409eb..43bbcb159d 100644 --- a/markets/spot-market/contracts/mocks/FeeCollectorMock.sol +++ b/markets/spot-market/contracts/mocks/FeeCollectorMock.sol @@ -17,6 +17,11 @@ contract FeeCollectorMock is IFeeCollector { address sender, uint8 tradeType ) external override returns (uint256) { + // mention the variables in the block to prevent unused local variable warning + marketId; + sender; + tradeType; + uint256 feeToCollect = feeAmount / 2; return feeToCollect; } diff --git a/markets/spot-market/contracts/mocks/OracleVerifierMock.sol b/markets/spot-market/contracts/mocks/OracleVerifierMock.sol index fb61d67980..38b8cfe4a2 100644 --- a/markets/spot-market/contracts/mocks/OracleVerifierMock.sol +++ b/markets/spot-market/contracts/mocks/OracleVerifierMock.sol @@ -18,6 +18,10 @@ contract OracleVerifierMock is IPythVerifier, IChainlinkVerifier { uint64 minPublishTime, uint64 maxPublishTime ) external payable override returns (IPythVerifier.PriceFeed[] memory priceFeeds) { + // mention the variables in the block to prevent unused local variable warning + updateData; + maxPublishTime; + priceFeeds = new IPythVerifier.PriceFeed[](1); priceFeeds[0] = IPythVerifier.PriceFeed({ @@ -41,12 +45,16 @@ contract OracleVerifierMock is IPythVerifier, IChainlinkVerifier { function verify( bytes memory chainlinkBlob ) external view override returns (bytes memory verifierResponse) { + // mention the variables in the block to prevent unused local variable warning + chainlinkBlob; // solhint-disable-next-line numcast/safe-cast int192 priceFormatted = int192(price) * 10 ** 18; verifierResponse = abi.encode("ETH-USD", block.timestamp, 10, priceFormatted); } function getUpdateFee(uint256 updateDataSize) external view override returns (uint256) { + // mention the variables in the block to prevent unused local variable warning + updateDataSize; return 1; } } diff --git a/protocol/governance/contracts/modules/council-nft/CouncilTokenModule.sol b/protocol/governance/contracts/modules/council-nft/CouncilTokenModule.sol index bb2be96cb7..ed44af74ab 100644 --- a/protocol/governance/contracts/modules/council-nft/CouncilTokenModule.sol +++ b/protocol/governance/contracts/modules/council-nft/CouncilTokenModule.sol @@ -10,6 +10,7 @@ import "@synthetixio/core-contracts/contracts/utils/SafeCast.sol"; * @title Module with custom NFT logic for the account token. * @dev See IAccountTokenModule. */ +// solhint-disable-next-line no-empty-blocks contract CouncilTokenModule is ICouncilTokenModule, NftModule { } diff --git a/protocol/governance/contracts/submodules/election/ElectionCredentials.sol b/protocol/governance/contracts/submodules/election/ElectionCredentials.sol index 796fccb297..955002cb36 100644 --- a/protocol/governance/contracts/submodules/election/ElectionCredentials.sol +++ b/protocol/governance/contracts/submodules/election/ElectionCredentials.sol @@ -14,7 +14,7 @@ contract ElectionCredentials is ElectionBase { using Council for Council.Data; using AssociatedSystem for AssociatedSystem.Data; - bytes32 constant _COUNCIL_NFT_SYSTEM = "councilToken"; + bytes32 internal constant _COUNCIL_NFT_SYSTEM = "councilToken"; function _removeAllCouncilMembers(uint epochIndex) internal { SetUtil.AddressSet storage members = Council.load().councilMembers; diff --git a/protocol/oracle-manager/contracts/mocks/pyth/MockPyth.sol b/protocol/oracle-manager/contracts/mocks/pyth/MockPyth.sol index c73d2d6c29..c7066fc20b 100644 --- a/protocol/oracle-manager/contracts/mocks/pyth/MockPyth.sol +++ b/protocol/oracle-manager/contracts/mocks/pyth/MockPyth.sol @@ -6,11 +6,11 @@ import "./PythStructs.sol"; import "./PythErrors.sol"; contract MockPyth is AbstractPyth { - mapping(bytes32 => PythStructs.PriceFeed) priceFeeds; - uint64 sequenceNumber; + mapping(bytes32 => PythStructs.PriceFeed) internal priceFeeds; + uint64 internal sequenceNumber; - uint singleUpdateFeeInWei; - uint validTimePeriod; + uint internal singleUpdateFeeInWei; + uint internal validTimePeriod; constructor(uint _validTimePeriod, uint _singleUpdateFeeInWei) { singleUpdateFeeInWei = _singleUpdateFeeInWei; diff --git a/protocol/synthetix/contracts/interfaces/external/IOracleManager.sol b/protocol/synthetix/contracts/interfaces/external/IOracleManager.sol index b62f10f30b..167504559c 100644 --- a/protocol/synthetix/contracts/interfaces/external/IOracleManager.sol +++ b/protocol/synthetix/contracts/interfaces/external/IOracleManager.sol @@ -4,6 +4,7 @@ pragma solidity >=0.8.11 <0.9.0; import "@synthetixio/oracle-manager/contracts/interfaces/INodeModule.sol"; /// @title Effective interface for the oracle manager +// solhint-disable-next-line no-empty-blocks interface IOracleManager is INodeModule { } diff --git a/protocol/synthetix/contracts/mocks/CcipRouterMock.sol b/protocol/synthetix/contracts/mocks/CcipRouterMock.sol index 3845a4f7c3..e42d2de5d2 100644 --- a/protocol/synthetix/contracts/mocks/CcipRouterMock.sol +++ b/protocol/synthetix/contracts/mocks/CcipRouterMock.sol @@ -4,6 +4,7 @@ pragma solidity >=0.8.4; import "../interfaces/external/ICcipRouterClient.sol"; contract CcipRouterMock { + // solhint-disable no-empty-blocks function ccipSend( uint64 destinationChainId, CcipClient.EVM2AnyMessage calldata message @@ -13,4 +14,5 @@ contract CcipRouterMock { uint64 destinationChainId, CcipClient.EVM2AnyMessage memory message ) external view virtual returns (uint256 fee) {} + // solhint-enable no-empty-blocks } diff --git a/protocol/synthetix/contracts/storage/Vault.sol b/protocol/synthetix/contracts/storage/Vault.sol index 9e01a0d313..6ff9e52cc9 100644 --- a/protocol/synthetix/contracts/storage/Vault.sol +++ b/protocol/synthetix/contracts/storage/Vault.sol @@ -51,6 +51,7 @@ library Vault { /** * @dev The previous debt of the vault, when `updateCreditCapacity` was last called by the Pool. */ + // solhint-disable-next-line var-name-mixedcase int128 _unused_prevTotalDebtD18; /** * @dev Vault data for all the liquidation cycles divided into epochs. From bd7b5ceca456b72200a27058b37a7aafff172006 Mon Sep 17 00:00:00 2001 From: Leonardo Massazza Date: Tue, 18 Jul 2023 13:47:34 +0100 Subject: [PATCH 08/63] Prevent Collateral updates with pending orders (#1711) * wip * yarn dedupe * upgrade missing deps * Prevent also new orders with pending one * wip * checkpoint * revert change * add tests * lint * change location of async order (#1720) * remove hasPendingOrder flag * Use load instead of mapping for AsyncOrder (#1721) * Use load instead of mapping for AsyncOrder * small fix * cleanup * PR Fixes --- .../interfaces/IAsyncOrderModule.sol | 5 - .../contracts/modules/AsyncOrderModule.sol | 26 ++- .../modules/AsyncOrderSettlementModule.sol | 4 +- .../contracts/modules/PerpsAccountModule.sol | 2 + .../contracts/storage/AsyncOrder.sol | 58 +++++- .../contracts/storage/PerpsAccount.sol | 14 +- .../contracts/storage/PerpsMarket.sol | 2 - markets/perps-market/storage.dump.sol | 7 +- .../Orders/OffchainAsyncOrder.pending.test.ts | 184 ++++++++++++++++++ .../Orders/OffchainAsyncOrder.settle.test.ts | 4 +- 10 files changed, 276 insertions(+), 30 deletions(-) create mode 100644 markets/perps-market/test/integration/Orders/OffchainAsyncOrder.pending.test.ts diff --git a/markets/perps-market/contracts/interfaces/IAsyncOrderModule.sol b/markets/perps-market/contracts/interfaces/IAsyncOrderModule.sol index a3478f0d8f..2b7cbd7ff7 100644 --- a/markets/perps-market/contracts/interfaces/IAsyncOrderModule.sol +++ b/markets/perps-market/contracts/interfaces/IAsyncOrderModule.sol @@ -47,11 +47,6 @@ interface IAsyncOrderModule { uint256 acceptablePrice ); - /** - * @notice Gets thrown when commit order is called when a pending order already exists. - */ - error OrderAlreadyCommitted(uint128 marketId, uint128 accountId); - /** * @notice Commit an async order via this function * @param commitment Order commitment data (see AsyncOrder.OrderCommitmentRequest struct). diff --git a/markets/perps-market/contracts/modules/AsyncOrderModule.sol b/markets/perps-market/contracts/modules/AsyncOrderModule.sol index 8111d75cda..6941542fe7 100644 --- a/markets/perps-market/contracts/modules/AsyncOrderModule.sol +++ b/markets/perps-market/contracts/modules/AsyncOrderModule.sol @@ -6,6 +6,7 @@ import {DecimalMath} from "@synthetixio/core-contracts/contracts/utils/DecimalMa import {Account} from "@synthetixio/main/contracts/storage/Account.sol"; import {AccountRBAC} from "@synthetixio/main/contracts/storage/AccountRBAC.sol"; import {IPythVerifier} from "../interfaces/external/IPythVerifier.sol"; +import {IAccountModule} from "../interfaces/IAccountModule.sol"; import {IAsyncOrderModule} from "../interfaces/IAsyncOrderModule.sol"; import {PerpsAccount, SNX_USD_MARKET_ID} from "../storage/PerpsAccount.sol"; import {MathUtil} from "../utils/MathUtil.sol"; @@ -37,6 +38,7 @@ contract AsyncOrderModule is IAsyncOrderModule { using Position for Position.Data; using SafeCastU256 for uint256; using SafeCastI256 for int256; + using PerpsAccount for PerpsAccount.Data; /** * @inheritdoc IAsyncOrderModule @@ -44,7 +46,7 @@ contract AsyncOrderModule is IAsyncOrderModule { function commitOrder( AsyncOrder.OrderCommitmentRequest memory commitment ) external override returns (AsyncOrder.Data memory retOrder, uint fees) { - PerpsMarket.Data storage market = PerpsMarket.loadValid(commitment.marketId); + PerpsMarket.loadValid(commitment.marketId); // Check if commitment.accountId is valid Account.exists(commitment.accountId); @@ -57,11 +59,10 @@ contract AsyncOrderModule is IAsyncOrderModule { GlobalPerpsMarket.load().checkLiquidation(commitment.accountId); - AsyncOrder.Data storage order = market.asyncOrders[commitment.accountId]; - - if (order.sizeDelta != 0) { - revert OrderAlreadyCommitted(commitment.marketId, commitment.accountId); - } + AsyncOrder.Data storage order = AsyncOrder.createValid( + commitment.accountId, + commitment.marketId + ); SettlementStrategy.Data storage strategy = PerpsMarketConfiguration .load(commitment.marketId) @@ -97,21 +98,26 @@ contract AsyncOrderModule is IAsyncOrderModule { function getOrder( uint128 marketId, uint128 accountId - ) public view override returns (AsyncOrder.Data memory) { - return PerpsMarket.loadValid(marketId).asyncOrders[accountId]; + ) external view override returns (AsyncOrder.Data memory order) { + order = AsyncOrder.load(accountId); + if (order.marketId != marketId) { + // return emtpy order if marketId does not match + order = AsyncOrder.Data(0, 0, 0, 0, 0, 0, 0); + } } /** * @inheritdoc IAsyncOrderModule */ function cancelOrder(uint128 marketId, uint128 accountId) external override { - AsyncOrder.Data storage order = PerpsMarket.loadValid(marketId).asyncOrders[accountId]; - order.checkValidity(); + AsyncOrder.Data storage order = AsyncOrder.loadValid(accountId, marketId); + SettlementStrategy.Data storage settlementStrategy = PerpsMarketConfiguration .load(marketId) .settlementStrategies[order.settlementStrategyId]; order.checkCancellationEligibility(settlementStrategy); order.reset(); + emit OrderCanceled(marketId, accountId, order.settlementTime, order.acceptablePrice); } } diff --git a/markets/perps-market/contracts/modules/AsyncOrderSettlementModule.sol b/markets/perps-market/contracts/modules/AsyncOrderSettlementModule.sol index c1e83527f0..e9aad91201 100644 --- a/markets/perps-market/contracts/modules/AsyncOrderSettlementModule.sol +++ b/markets/perps-market/contracts/modules/AsyncOrderSettlementModule.sol @@ -203,12 +203,12 @@ contract AsyncOrderSettlementModule is IAsyncOrderSettlementModule, IMarketEvent uint128 marketId, uint128 accountId ) private view returns (AsyncOrder.Data storage, SettlementStrategy.Data storage) { - AsyncOrder.Data storage order = PerpsMarket.loadValid(marketId).asyncOrders[accountId]; + AsyncOrder.Data storage order = AsyncOrder.loadValid(accountId, marketId); + SettlementStrategy.Data storage settlementStrategy = PerpsMarketConfiguration .load(marketId) .settlementStrategies[order.settlementStrategyId]; - order.checkValidity(); order.checkWithinSettlementWindow(settlementStrategy); return (order, settlementStrategy); diff --git a/markets/perps-market/contracts/modules/PerpsAccountModule.sol b/markets/perps-market/contracts/modules/PerpsAccountModule.sol index 2f04d7e763..989faaa267 100644 --- a/markets/perps-market/contracts/modules/PerpsAccountModule.sol +++ b/markets/perps-market/contracts/modules/PerpsAccountModule.sol @@ -54,6 +54,8 @@ contract PerpsAccountModule is IAccountModule { account.id = accountId; } + account.checkPendingOrder(); + ITokenModule synth = synthMarketId == 0 ? perpsMarketFactory.usdToken : ITokenModule(perpsMarketFactory.spotMarket.getSynth(synthMarketId)); diff --git a/markets/perps-market/contracts/storage/AsyncOrder.sol b/markets/perps-market/contracts/storage/AsyncOrder.sol index 5697824b86..e570925650 100644 --- a/markets/perps-market/contracts/storage/AsyncOrder.sol +++ b/markets/perps-market/contracts/storage/AsyncOrder.sol @@ -37,9 +37,19 @@ library AsyncOrder { uint256 settlementExpiration ); + error AcceptablePriceExceeded(uint256 acceptablePrice, uint256 fillPrice); + error OrderNotValid(); - error AcceptablePriceExceeded(uint256 acceptablePrice, uint256 fillPrice); + /** + * @notice Gets thrown when commit order is called when a pending order already exists. + */ + error OrderAlreadyCommitted(uint128 marketId, uint128 accountId); + + /** + * @notice Gets thrown when pending orders exist and attempts to modify collateral. + */ + error PendingOrderExist(); struct Data { uint128 accountId; @@ -60,6 +70,46 @@ library AsyncOrder { bytes32 trackingCode; } + function load(uint128 accountId) internal pure returns (Data storage order) { + bytes32 s = keccak256(abi.encode("io.synthetix.perps-market.AsyncOrder", accountId)); + + assembly { + order.slot := s + } + } + + /** + * @dev Reverts if the order does not belongs to the market or not exists. Otherwise, returns the order. + * @dev non-existent order is considered an order with sizeDelta == 0. + */ + function loadValid( + uint128 accountId, + uint128 marketId + ) internal view returns (Data storage order) { + order = load(accountId); + if (order.marketId != marketId || order.sizeDelta == 0) { + revert OrderNotValid(); + } + } + + /** + * @dev Reverts if the order does not belongs to the market or not exists. Otherwise, returns the order. + * @dev non-existent order is considered an order with sizeDelta == 0. + */ + function createValid( + uint128 accountId, + uint128 marketId + ) internal view returns (Data storage order) { + order = load(accountId); + if (order.sizeDelta != 0 && order.marketId == marketId) { + revert OrderAlreadyCommitted(marketId, accountId); + } + + if (order.sizeDelta != 0) { + revert PendingOrderExist(); + } + } + function update( Data storage self, OrderCommitmentRequest memory commitment, @@ -110,12 +160,6 @@ library AsyncOrder { } } - function checkValidity(Data storage self) internal view { - if (self.sizeDelta == 0) { - revert OrderNotValid(); - } - } - error ZeroSizeOrder(); error InsufficientMargin(int availableMargin, uint minMargin); diff --git a/markets/perps-market/contracts/storage/PerpsAccount.sol b/markets/perps-market/contracts/storage/PerpsAccount.sol index 7833f6a771..c71462edf3 100644 --- a/markets/perps-market/contracts/storage/PerpsAccount.sol +++ b/markets/perps-market/contracts/storage/PerpsAccount.sol @@ -9,6 +9,7 @@ import {Position} from "./Position.sol"; import {PerpsMarket} from "./PerpsMarket.sol"; import {MathUtil} from "../utils/MathUtil.sol"; import {PerpsPrice} from "./PerpsPrice.sol"; +import {AsyncOrder} from "./AsyncOrder.sol"; import {PerpsMarketFactory} from "./PerpsMarketFactory.sol"; import {GlobalPerpsMarket} from "./GlobalPerpsMarket.sol"; import {GlobalPerpsMarketConfiguration} from "./GlobalPerpsMarketConfiguration.sol"; @@ -34,10 +35,13 @@ library PerpsAccount { using DecimalMath for uint256; struct Data { - // synth marketId => amount + // @dev synth marketId => amount mapping(uint128 => uint256) collateralAmounts; + // @dev account Id uint128 id; + // @dev set of active collateral types. By active we mean collateral types that have a non-zero amount SetUtil.UintSet activeCollateralTypes; + // @dev set of open position market ids SetUtil.UintSet openPositionMarketIds; } @@ -89,6 +93,14 @@ library PerpsAccount { } } + function checkPendingOrder(Data storage self) internal { + // Check if there are pending orders + AsyncOrder.Data memory asyncOrder = AsyncOrder.load(self.id); + if (asyncOrder.sizeDelta != 0) { + revert AsyncOrder.PendingOrderExist(); + } + } + function addCollateralAmount( Data storage self, uint128 synthMarketId, diff --git a/markets/perps-market/contracts/storage/PerpsMarket.sol b/markets/perps-market/contracts/storage/PerpsMarket.sol index 559d8003db..7a16f15ebe 100644 --- a/markets/perps-market/contracts/storage/PerpsMarket.sol +++ b/markets/perps-market/contracts/storage/PerpsMarket.sol @@ -45,8 +45,6 @@ library PerpsMarket { // liquidation data uint128 lastTimeLiquidationCapacityUpdated; uint128 lastUtilizedLiquidationCapacity; - // accountId => asyncOrder - mapping(uint => AsyncOrder.Data) asyncOrders; // accountId => position mapping(uint => Position.Data) positions; } diff --git a/markets/perps-market/storage.dump.sol b/markets/perps-market/storage.dump.sol index 263bcb9c0d..66c6e48d88 100644 --- a/markets/perps-market/storage.dump.sol +++ b/markets/perps-market/storage.dump.sol @@ -500,6 +500,12 @@ library AsyncOrder { Position.Data newPosition; bytes32 trackingCode; } + function load(uint128 accountId) internal pure returns (Data storage order) { + bytes32 s = keccak256(abi.encode("io.synthetix.perps-market.AsyncOrder", accountId)); + assembly { + order.slot := s + } + } } // @custom:artifact contracts/storage/GlobalPerpsMarket.sol:GlobalPerpsMarket @@ -586,7 +592,6 @@ library PerpsMarket { uint256 lastFundingTime; uint128 lastTimeLiquidationCapacityUpdated; uint128 lastUtilizedLiquidationCapacity; - mapping(uint => AsyncOrder.Data) asyncOrders; mapping(uint => Position.Data) positions; } struct MarketUpdateData { diff --git a/markets/perps-market/test/integration/Orders/OffchainAsyncOrder.pending.test.ts b/markets/perps-market/test/integration/Orders/OffchainAsyncOrder.pending.test.ts new file mode 100644 index 0000000000..1421f549c7 --- /dev/null +++ b/markets/perps-market/test/integration/Orders/OffchainAsyncOrder.pending.test.ts @@ -0,0 +1,184 @@ +import { ethers } from 'ethers'; +import { DEFAULT_SETTLEMENT_STRATEGY, bn, bootstrapMarkets } from '../bootstrap'; +import { fastForwardTo } from '@synthetixio/core-utils/utils/hardhat/rpc'; +import { snapshotCheckpoint } from '@synthetixio/core-utils/utils/mocha/snapshot'; +import { depositCollateral, settleOrder } from '../helpers'; +import assertBn from '@synthetixio/core-utils/utils/assertions/assert-bignumber'; +import assertRevert from '@synthetixio/core-utils/utils/assertions/assert-revert'; +import { getTxTime } from '@synthetixio/core-utils/src/utils/hardhat/rpc'; + +describe('Offchain Async Order - Prevent updates with pending order test', () => { + const { systems, perpsMarkets, provider, trader1, keeper } = bootstrapMarkets({ + synthMarkets: [], + perpsMarkets: [ + { + name: 'Ether', + token: 'snxETH', + price: bn(1000), + fundingParams: { skewScale: bn(100_000), maxFundingVelocity: bn(10) }, + }, + { + name: 'Bitcoin', + token: 'snxBTC', + price: bn(10_000), + fundingParams: { skewScale: bn(100_000), maxFundingVelocity: bn(10) }, + }, + ], + traderAccountIds: [2, 3], + }); + let ethMarketId: ethers.BigNumber; + let btcMarketId: ethers.BigNumber; + + before('identify actors', async () => { + ethMarketId = perpsMarkets()[0].marketId(); + btcMarketId = perpsMarkets()[1].marketId(); + }); + + describe('With a pending order', () => { + let startTime: number; + before('add collateral', async () => { + await depositCollateral({ + systems, + trader: trader1, + accountId: () => 2, + collaterals: [ + { + snxUSDAmount: () => bn(10_000), + }, + ], + }); + }); + + before('commit the order', async () => { + const tx = await systems() + .PerpsMarket.connect(trader1()) + .commitOrder({ + marketId: ethMarketId, + accountId: 2, + sizeDelta: bn(1), + settlementStrategyId: 0, + acceptablePrice: bn(1050), // 5% slippage + trackingCode: ethers.constants.HashZero, + }); + startTime = await getTxTime(provider(), tx); + }); + + const restoreToCommit = snapshotCheckpoint(provider); + + describe('failures', () => { + before(restoreToCommit); + + it('reverts if attempt to update collateral', async () => { + await assertRevert( + systems().PerpsMarket.connect(trader1()).modifyCollateral(2, 0, bn(10)), + 'PendingOrderExist()', + systems().PerpsMarket + ); + }); + + it('reverts if attempt to commit another order', async () => { + await assertRevert( + systems() + .PerpsMarket.connect(trader1()) + .commitOrder({ + marketId: btcMarketId, + accountId: 2, + sizeDelta: bn(0.01), + settlementStrategyId: 0, + acceptablePrice: bn(10050), // 5% slippage + trackingCode: ethers.constants.HashZero, + }), + 'PendingOrderExist()', + systems().PerpsMarket + ); + }); + }); + + describe('after settle the pending order', () => { + before(restoreToCommit); + + before('settle the order', async () => { + const settlementTime = startTime + DEFAULT_SETTLEMENT_STRATEGY.settlementDelay + 1; + await fastForwardTo(settlementTime, provider()); + await settleOrder({ + systems, + keeper: keeper(), + marketId: ethMarketId, + accountId: 2, + feedId: DEFAULT_SETTLEMENT_STRATEGY.feedId, + settlementTime, + offChainPrice: 1000, + }); + }); + + it('can update the collateral', async () => { + const collateralBalancBefore = await systems().PerpsMarket.getCollateralAmount(2, 0); + + await systems().PerpsMarket.connect(trader1()).modifyCollateral(2, 0, bn(10)); + + const collateralBalancAfter = await systems().PerpsMarket.getCollateralAmount(2, 0); + assertBn.equal(collateralBalancAfter, collateralBalancBefore.add(bn(10))); + }); + + it('can commit another order', async () => { + await systems() + .PerpsMarket.connect(trader1()) + .commitOrder({ + marketId: btcMarketId, + accountId: 2, + sizeDelta: bn(1), + settlementStrategyId: 0, + acceptablePrice: bn(10050), // 5% slippage + trackingCode: ethers.constants.HashZero, + }); + + const order = await systems().PerpsMarket.getOrder(btcMarketId, 2); + assertBn.equal(order.accountId, 2); + assertBn.equal(order.marketId, btcMarketId); + assertBn.equal(order.sizeDelta, bn(1)); + }); + }); + + describe('after cancel the pending order', () => { + before(restoreToCommit); + + before('cancel the order', async () => { + await fastForwardTo( + startTime + + DEFAULT_SETTLEMENT_STRATEGY.settlementDelay + + DEFAULT_SETTLEMENT_STRATEGY.settlementWindowDuration + + 1, + provider() + ); + await systems().PerpsMarket.cancelOrder(ethMarketId, 2); + }); + + it('can update the collateral', async () => { + const collateralBalancBefore = await systems().PerpsMarket.getCollateralAmount(2, 0); + + await systems().PerpsMarket.connect(trader1()).modifyCollateral(2, 0, bn(10)); + + const collateralBalancAfter = await systems().PerpsMarket.getCollateralAmount(2, 0); + assertBn.equal(collateralBalancAfter, collateralBalancBefore.add(bn(10))); + }); + + it('can commit another order', async () => { + await systems() + .PerpsMarket.connect(trader1()) + .commitOrder({ + marketId: btcMarketId, + accountId: 2, + sizeDelta: bn(1), + settlementStrategyId: 0, + acceptablePrice: bn(10050), // 5% slippage + trackingCode: ethers.constants.HashZero, + }); + + const order = await systems().PerpsMarket.getOrder(btcMarketId, 2); + assertBn.equal(order.accountId, 2); + assertBn.equal(order.marketId, btcMarketId); + assertBn.equal(order.sizeDelta, bn(1)); + }); + }); + }); +}); diff --git a/markets/perps-market/test/integration/Orders/OffchainAsyncOrder.settle.test.ts b/markets/perps-market/test/integration/Orders/OffchainAsyncOrder.settle.test.ts index e628bc8a96..9c4f110f1a 100644 --- a/markets/perps-market/test/integration/Orders/OffchainAsyncOrder.settle.test.ts +++ b/markets/perps-market/test/integration/Orders/OffchainAsyncOrder.settle.test.ts @@ -45,7 +45,7 @@ describe('Settle Offchain Async Order test', () => { it('reverts if market id is incorrect', async () => { await assertRevert( systems().PerpsMarket.connect(trader1()).settle(1337, 2), - 'InvalidMarket("1337")' + 'OrderNotValid()' ); }); @@ -88,7 +88,7 @@ describe('Settle Offchain Async Order test', () => { systems() .PerpsMarket.connect(keeper()) .settlePythOrder(pythPriceData, extraData, { value: updateFee }), - 'InvalidMarket("1337")' + 'OrderNotValid()' ); }); From fb63e9ccd99576bdaa2da8825a7c73fc782e0bfe Mon Sep 17 00:00:00 2001 From: Sunny Vempati Date: Thu, 20 Jul 2023 04:55:38 -0500 Subject: [PATCH 09/63] Super market (#1691) * supermarket * deposit margin * liq * fix update position * cleanup * cleanup * deduct account fixes * requested market id * test fixes * fix liq test * fix lint * review fixes * bug * fix initialize * fix conversion * remove comments * Fix storage dump --------- Co-authored-by: joey --- markets/perps-market/cannonfile.toml | 6 + .../IAsyncOrderSettlementModule.sol | 5 +- .../interfaces/IMarketConfigurationModule.sol | 14 + .../interfaces/IPerpsMarketFactoryModule.sol | 31 +- .../interfaces/IPerpsMarketModule.sol | 4 + .../interfaces/external/ISynthetixSystem.sol | 8 +- .../modules/AsyncOrderSettlementModule.sol | 40 ++- .../modules/MarketConfigurationModule.sol | 29 +- .../contracts/modules/PerpsAccountModule.sol | 71 ++-- .../modules/PerpsMarketFactoryModule.sol | 110 +++---- .../contracts/modules/PerpsMarketModule.sol | 8 + .../contracts/storage/GlobalPerpsMarket.sol | 56 +++- .../contracts/storage/PerpsAccount.sol | 304 +++++++----------- .../contracts/storage/PerpsMarket.sol | 60 ++-- .../contracts/storage/PerpsMarketFactory.sol | 29 +- markets/perps-market/storage.dump.sol | 23 +- .../Account/ModifyCollateral.deposit.test.ts | 21 +- .../Account/ModifyCollateral.withdraw.test.ts | 34 +- .../Liquidation/Liquidation.margin.test.ts | 9 +- .../Liquidation.maxLiquidationAmount.test.ts | 1 + .../integration/Market/CreateMarket.test.ts | 269 +++++++--------- .../Market/MarketConfiguration.test.ts | 53 ++- .../Market/PerpsMarketModule.test.ts | 5 +- .../test/integration/Market/Size.test.ts | 1 + .../Markets/GlobalPerpsMarket.test.ts | 2 +- .../Orders/OffchainAsyncOrder.cancel.test.ts | 7 +- .../Orders/OffchainAsyncOrder.commit.test.ts | 1 + .../Orders/OffchainAsyncOrder.fees.test.ts | 36 +-- .../Orders/OffchainAsyncOrder.pending.test.ts | 2 + .../Orders/OffchainAsyncOrder.price.test.ts | 1 + .../Orders/OffchainAsyncOrder.settle.test.ts | 2 + .../test/integration/Position/Funding.test.ts | 1 + .../test/integration/bootstrap/bootstrap.ts | 15 +- .../bootstrap/bootstrapPerpsMarkets.ts | 54 ++-- .../test/common/bootstrapSynthMarkets.ts | 19 +- 35 files changed, 651 insertions(+), 680 deletions(-) diff --git a/markets/perps-market/cannonfile.toml b/markets/perps-market/cannonfile.toml index a5c5c6421e..7ba7053e5f 100644 --- a/markets/perps-market/cannonfile.toml +++ b/markets/perps-market/cannonfile.toml @@ -156,3 +156,9 @@ func = "addToFeatureFlagAllowlist" from = "<%= settings.owner %>" args = ["<%= formatBytes32String('createMarket') %>", "<%= settings.owner %>"] depends = ['invoke.setSynthetix'] + +[invoke.initializeFactory] +target = ["PerpsMarketProxy"] +func = "initializeFactory" +from = "<%= settings.owner %>" +depends = ['invoke.setSynthetix'] diff --git a/markets/perps-market/contracts/interfaces/IAsyncOrderSettlementModule.sol b/markets/perps-market/contracts/interfaces/IAsyncOrderSettlementModule.sol index 1cc0e2ad43..447f59ff32 100644 --- a/markets/perps-market/contracts/interfaces/IAsyncOrderSettlementModule.sol +++ b/markets/perps-market/contracts/interfaces/IAsyncOrderSettlementModule.sol @@ -1,6 +1,7 @@ //SPDX-License-Identifier: MIT pragma solidity >=0.8.11 <0.9.0; import {SettlementStrategy} from "../storage/SettlementStrategy.sol"; +import {PerpsMarketFactory} from "../storage/PerpsMarketFactory.sol"; interface IAsyncOrderSettlementModule { /** @@ -34,6 +35,7 @@ interface IAsyncOrderSettlementModule { uint128 indexed marketId, uint128 indexed accountId, uint256 fillPrice, + int256 pnl, int128 sizeDelta, int128 newSize, uint256 collectedFees, @@ -50,8 +52,9 @@ interface IAsyncOrderSettlementModule { int128 sizeDelta; int256 pnl; uint256 pnlUint; - uint256 amountToDeposit; + uint256 amountToDeduct; uint256 settlementReward; + PerpsMarketFactory.Data factory; } /** diff --git a/markets/perps-market/contracts/interfaces/IMarketConfigurationModule.sol b/markets/perps-market/contracts/interfaces/IMarketConfigurationModule.sol index 3a338b9eee..6a3b8b39c9 100644 --- a/markets/perps-market/contracts/interfaces/IMarketConfigurationModule.sol +++ b/markets/perps-market/contracts/interfaces/IMarketConfigurationModule.sol @@ -21,6 +21,13 @@ interface IMarketConfigurationModule { uint256 indexed strategyId ); + /** + * @notice Gets fired when feed id for perps market is updated. + * @param marketId id of perps market + * @param feedId oracle node id + */ + event MarketPriceDataUpdated(uint128 indexed marketId, bytes32 feedId); + /** * @notice Gets fired when order fees are updated. * @param marketId udpates fees to this specific market. @@ -102,6 +109,13 @@ interface IMarketConfigurationModule { */ function setOrderFees(uint128 marketId, uint256 makerFeeRatio, uint256 takerFeeRatio) external; + /** + * @notice Set node id for perps market + * @param perpsMarketId id of the market to set price feed. + * @param feedId the node feed id + */ + function updatePriceData(uint128 perpsMarketId, bytes32 feedId) external; + /** * @notice Set funding parameters for a market with this function. * @param marketId id of the market to set funding parameters. diff --git a/markets/perps-market/contracts/interfaces/IPerpsMarketFactoryModule.sol b/markets/perps-market/contracts/interfaces/IPerpsMarketFactoryModule.sol index 3d1b6fc344..c35ec33f9d 100644 --- a/markets/perps-market/contracts/interfaces/IPerpsMarketFactoryModule.sol +++ b/markets/perps-market/contracts/interfaces/IPerpsMarketFactoryModule.sol @@ -6,39 +6,18 @@ import {ISynthetixSystem} from "./external/ISynthetixSystem.sol"; import {ISpotMarketSystem} from "./external/ISpotMarketSystem.sol"; interface IPerpsMarketFactoryModule is IMarket { - event MarketRegistered( - uint128 indexed perpsMarketId, - address indexed marketOwner, - string marketName, - string marketSymbol - ); - event MarketOwnerNominated(uint128 indexed perpsMarketId, address indexed newNominatedOwner); - event MarketOwnerChanged( - uint128 indexed perpsMarketId, - address indexed oldOwner, - address indexed newOwner - ); - event MarketPriceDataUpdated(uint128 indexed perpsMarketId, bytes32 feedId); + event FactoryInitialized(uint128 globalPerpsMarketId); + event MarketCreated(uint128 indexed perpsMarketId, string marketName, string marketSymbol); - error NotNominated(address notNominatedAddress); + function initializeFactory() external returns (uint128); function setSynthetix(ISynthetixSystem synthetix) external; function setSpotMarket(ISpotMarketSystem spotMarket) external; function createMarket( + uint128 requestedMarketId, string memory marketName, - string memory marketSymbol, - address marketOwner + string memory marketSymbol ) external returns (uint128); - - function symbol(uint128 marketId) external view returns (string memory); - - function updatePriceData(uint128 perpsMarketId, bytes32 feedId) external; - - function nominateMarketOwner(uint128 perpsMarketId, address newNominatedOwner) external; - - function acceptMarketOwnership(uint128 perpsMarketId) external; - - function getMarketOwner(uint128 perpsMarketId) external view returns (address); } diff --git a/markets/perps-market/contracts/interfaces/IPerpsMarketModule.sol b/markets/perps-market/contracts/interfaces/IPerpsMarketModule.sol index 819345bc67..e2d6e868e5 100644 --- a/markets/perps-market/contracts/interfaces/IPerpsMarketModule.sol +++ b/markets/perps-market/contracts/interfaces/IPerpsMarketModule.sol @@ -16,6 +16,10 @@ interface IPerpsMarketModule { uint indexPrice; } + function metadata( + uint128 marketId + ) external view returns (string memory name, string memory symbol); + function skew(uint128 marketId) external view returns (int256); function size(uint128 marketId) external view returns (uint256); diff --git a/markets/perps-market/contracts/interfaces/external/ISynthetixSystem.sol b/markets/perps-market/contracts/interfaces/external/ISynthetixSystem.sol index dbb26c9219..429717d4d0 100644 --- a/markets/perps-market/contracts/interfaces/external/ISynthetixSystem.sol +++ b/markets/perps-market/contracts/interfaces/external/ISynthetixSystem.sol @@ -3,9 +3,15 @@ pragma solidity >=0.8.11 <0.9.0; import {IAssociatedSystemsModule} from "@synthetixio/core-modules/contracts/interfaces/IAssociatedSystemsModule.sol"; import {IMarketManagerModule} from "@synthetixio/main/contracts/interfaces/IMarketManagerModule.sol"; +import {IMarketCollateralModule} from "@synthetixio/main/contracts/interfaces/IMarketCollateralModule.sol"; import {IUtilsModule} from "@synthetixio/main/contracts/interfaces/IUtilsModule.sol"; // solhint-disable-next-line no-empty-blocks -interface ISynthetixSystem is IAssociatedSystemsModule, IMarketManagerModule, IUtilsModule { +interface ISynthetixSystem is + IAssociatedSystemsModule, + IMarketCollateralModule, + IMarketManagerModule, + IUtilsModule +{ } diff --git a/markets/perps-market/contracts/modules/AsyncOrderSettlementModule.sol b/markets/perps-market/contracts/modules/AsyncOrderSettlementModule.sol index e9aad91201..11b7877bc0 100644 --- a/markets/perps-market/contracts/modules/AsyncOrderSettlementModule.sol +++ b/markets/perps-market/contracts/modules/AsyncOrderSettlementModule.sol @@ -120,10 +120,8 @@ contract AsyncOrderSettlementModule is IAsyncOrderSettlementModule, IMarketEvent SettlementStrategy.Data storage settlementStrategy ) private { SettleOrderRuntime memory runtime; - runtime.accountId = asyncOrder.accountId; runtime.marketId = asyncOrder.marketId; - // check if account is flagged GlobalPerpsMarket.load().checkLiquidation(runtime.accountId); ( @@ -132,29 +130,28 @@ contract AsyncOrderSettlementModule is IAsyncOrderSettlementModule, IMarketEvent uint fillPrice, Position.Data storage oldPosition ) = asyncOrder.validateOrder(settlementStrategy, price); - runtime.newPositionSize = newPosition.size; runtime.sizeDelta = asyncOrder.sizeDelta; - PerpsMarketFactory.Data storage factory = PerpsMarketFactory.load(); + runtime.factory = PerpsMarketFactory.load(); PerpsAccount.Data storage perpsAccount = PerpsAccount.load(runtime.accountId); + // use fill price to calculate realized pnl (runtime.pnl, , , ) = oldPosition.getPnl(fillPrice); - runtime.pnlUint = MathUtil.abs(runtime.pnl); + if (runtime.pnl > 0) { - factory.synthetix.withdrawMarketUsd(runtime.marketId, address(this), runtime.pnlUint); - perpsAccount.addCollateralAmount(SNX_USD_MARKET_ID, runtime.pnlUint); + perpsAccount.updateCollateralAmount(SNX_USD_MARKET_ID, runtime.pnl); } else if (runtime.pnl < 0) { - perpsAccount.deductFromAccount(runtime.pnlUint); - runtime.amountToDeposit = runtime.pnlUint; - // all gets deposited below with fees + runtime.amountToDeduct = runtime.pnlUint; } - // after pnl is realized, update position on the perps market, this will also update the position. + // after pnl is realized, update position PerpsMarket.MarketUpdateData memory updateData = PerpsMarket .loadValid(runtime.marketId) .updatePositionData(runtime.accountId, newPosition); + perpsAccount.updateOpenPositions(runtime.marketId, runtime.newPositionSize); + emit MarketUpdated( updateData.marketId, price, @@ -165,21 +162,21 @@ contract AsyncOrderSettlementModule is IAsyncOrderSettlementModule, IMarketEvent updateData.currentFundingVelocity ); - perpsAccount.updatePositionMarkets(runtime.marketId, runtime.newPositionSize); - perpsAccount.deductFromAccount(totalFees); - + // since margin is deposited, as long as the owed collateral is deducted + // fees are realized by the stakers + perpsAccount.deductFromAccount(runtime.amountToDeduct + totalFees); runtime.settlementReward = settlementStrategy.settlementReward; - runtime.amountToDeposit += totalFees - runtime.settlementReward; + if (runtime.settlementReward > 0) { // pay keeper - factory.usdToken.transfer(msg.sender, runtime.settlementReward); - } - - if (runtime.amountToDeposit > 0) { - // deposit into market manager - factory.depositToMarketManager(runtime.marketId, runtime.amountToDeposit); + runtime.factory.synthetix.withdrawMarketUsd( + runtime.factory.perpsMarketId, + msg.sender, + runtime.settlementReward + ); } + // trader can now commit a new order asyncOrder.reset(); // emit event @@ -187,6 +184,7 @@ contract AsyncOrderSettlementModule is IAsyncOrderSettlementModule, IMarketEvent runtime.marketId, runtime.accountId, fillPrice, + runtime.pnl, runtime.sizeDelta, runtime.newPositionSize, totalFees, diff --git a/markets/perps-market/contracts/modules/MarketConfigurationModule.sol b/markets/perps-market/contracts/modules/MarketConfigurationModule.sol index 94ad50c28b..228c2582d6 100644 --- a/markets/perps-market/contracts/modules/MarketConfigurationModule.sol +++ b/markets/perps-market/contracts/modules/MarketConfigurationModule.sol @@ -1,10 +1,12 @@ //SPDX-License-Identifier: MIT pragma solidity >=0.8.11 <0.9.0; +import {OwnableStorage} from "@synthetixio/core-contracts/contracts/ownership/OwnableStorage.sol"; import {IMarketConfigurationModule} from "../interfaces/IMarketConfigurationModule.sol"; import {SettlementStrategy} from "../storage/SettlementStrategy.sol"; import {PerpsMarketConfiguration} from "../storage/PerpsMarketConfiguration.sol"; import {PerpsMarket} from "../storage/PerpsMarket.sol"; +import {PerpsPrice} from "../storage/PerpsPrice.sol"; import {OrderFee} from "../storage/OrderFee.sol"; /** @@ -12,7 +14,7 @@ import {OrderFee} from "../storage/OrderFee.sol"; * @dev See IMarketConfigurationModule. */ contract MarketConfigurationModule is IMarketConfigurationModule { - using PerpsMarket for PerpsMarket.Data; + using PerpsPrice for PerpsPrice.Data; /** * @inheritdoc IMarketConfigurationModule @@ -21,7 +23,7 @@ contract MarketConfigurationModule is IMarketConfigurationModule { uint128 marketId, SettlementStrategy.Data memory strategy ) external override returns (uint256 strategyId) { - PerpsMarket.load(marketId).onlyMarketOwner(); + OwnableStorage.onlyOwner(); strategy.settlementDelay = strategy.settlementDelay == 0 ? 1 : strategy.settlementDelay; @@ -40,7 +42,7 @@ contract MarketConfigurationModule is IMarketConfigurationModule { uint256 strategyId, bool enabled ) external override { - PerpsMarket.load(marketId).onlyMarketOwner(); + OwnableStorage.onlyOwner(); PerpsMarketConfiguration .load(marketId) .settlementStrategies[strategyId] @@ -56,18 +58,29 @@ contract MarketConfigurationModule is IMarketConfigurationModule { uint256 makerFeeRatio, uint256 takerFeeRatio ) external override { - PerpsMarket.load(marketId).onlyMarketOwner(); + OwnableStorage.onlyOwner(); PerpsMarketConfiguration.Data storage config = PerpsMarketConfiguration.load(marketId); config.orderFees.makerFee = makerFeeRatio; config.orderFees.takerFee = takerFeeRatio; emit OrderFeesSet(marketId, makerFeeRatio, takerFeeRatio); } + /** + * @inheritdoc IMarketConfigurationModule + */ + function updatePriceData(uint128 perpsMarketId, bytes32 feedId) external override { + OwnableStorage.onlyOwner(); + + PerpsPrice.load(perpsMarketId).update(feedId); + + emit MarketPriceDataUpdated(perpsMarketId, feedId); + } + /** * @inheritdoc IMarketConfigurationModule */ function setMaxMarketSize(uint128 marketId, uint256 maxMarketSize) external override { - PerpsMarket.load(marketId).onlyMarketOwner(); + OwnableStorage.onlyOwner(); PerpsMarketConfiguration.Data storage config = PerpsMarketConfiguration.load(marketId); config.maxMarketSize = maxMarketSize; emit MaxMarketSizeSet(marketId, maxMarketSize); @@ -81,7 +94,7 @@ contract MarketConfigurationModule is IMarketConfigurationModule { uint256 skewScale, uint256 maxFundingVelocity ) external override { - PerpsMarket.load(marketId).onlyMarketOwner(); + OwnableStorage.onlyOwner(); PerpsMarketConfiguration.Data storage config = PerpsMarketConfiguration.load(marketId); config.maxFundingVelocity = maxFundingVelocity; @@ -101,7 +114,7 @@ contract MarketConfigurationModule is IMarketConfigurationModule { uint256 maxSecondsInLiquidationWindow, uint256 minimumPositionMargin ) external override { - PerpsMarket.load(marketId).onlyMarketOwner(); + OwnableStorage.onlyOwner(); PerpsMarketConfiguration.Data storage config = PerpsMarketConfiguration.load(marketId); config.initialMarginRatioD18 = initialMarginRatioD18; @@ -127,7 +140,7 @@ contract MarketConfigurationModule is IMarketConfigurationModule { * @inheritdoc IMarketConfigurationModule */ function setLockedOiRatio(uint128 marketId, uint256 lockedOiRatioD18) external override { - PerpsMarket.load(marketId).onlyMarketOwner(); + OwnableStorage.onlyOwner(); PerpsMarketConfiguration.Data storage config = PerpsMarketConfiguration.load(marketId); config.lockedOiRatioD18 = lockedOiRatioD18; emit LockedOiRatioD18Set(marketId, lockedOiRatioD18); diff --git a/markets/perps-market/contracts/modules/PerpsAccountModule.sol b/markets/perps-market/contracts/modules/PerpsAccountModule.sol index 989faaa267..2845069aac 100644 --- a/markets/perps-market/contracts/modules/PerpsAccountModule.sol +++ b/markets/perps-market/contracts/modules/PerpsAccountModule.sol @@ -26,6 +26,7 @@ contract PerpsAccountModule is IAccountModule { using SafeCastU256 for uint256; using SafeCastI256 for int256; using GlobalPerpsMarket for GlobalPerpsMarket.Data; + using PerpsMarketFactory for PerpsMarketFactory.Data; /** * @inheritdoc IAccountModule @@ -46,34 +47,26 @@ contract PerpsAccountModule is IAccountModule { PerpsMarketFactory.Data storage perpsMarketFactory = PerpsMarketFactory.load(); GlobalPerpsMarket.Data storage globalPerpsMarket = GlobalPerpsMarket.load(); - globalPerpsMarket.checkCollateralAmountAndAdjust(synthMarketId, amountDelta); + globalPerpsMarket.validateCollateralAmount(synthMarketId, amountDelta); globalPerpsMarket.checkLiquidation(accountId); - PerpsAccount.Data storage account = PerpsAccount.load(accountId); - if (account.id == 0) { - account.id = accountId; - } + PerpsAccount.Data storage account = PerpsAccount.create(accountId); + uint128 perpsMarketId = PerpsMarketFactory.load().perpsMarketId; account.checkPendingOrder(); - ITokenModule synth = synthMarketId == 0 - ? perpsMarketFactory.usdToken - : ITokenModule(perpsMarketFactory.spotMarket.getSynth(synthMarketId)); - if (amountDelta > 0) { - // adding collateral - account.addCollateralAmount(synthMarketId, amountDelta.toUint()); - - synth.transferFrom(msg.sender, address(this), amountDelta.toUint()); + _depositMargin(perpsMarketFactory, perpsMarketId, synthMarketId, amountDelta.toUint()); } else { - uint amountAbs = MathUtil.abs(amountDelta); + uint256 amountAbs = MathUtil.abs(amountDelta); // removing collateral - account.checkAvailableWithdrawableValue(amountAbs); - account.removeCollateralAmount(synthMarketId, amountAbs); - - synth.transfer(msg.sender, amountAbs); + account.validateWithdrawableAmount(amountAbs); + _withdrawMargin(perpsMarketFactory, perpsMarketId, synthMarketId, amountAbs); } + // accounting + account.updateCollateralAmount(synthMarketId, amountDelta); + emit CollateralModified(accountId, synthMarketId, amountDelta, msg.sender); } @@ -124,4 +117,46 @@ contract PerpsAccountModule is IAccountModule { ) external view override returns (uint256) { return PerpsAccount.load(accountId).collateralAmounts[synthMarketId]; } + + function _depositMargin( + PerpsMarketFactory.Data storage perpsMarketFactory, + uint128 perpsMarketId, + uint128 synthMarketId, + uint256 amount + ) internal { + if (synthMarketId == 0) { + // depositing into the USD market + perpsMarketFactory.synthetix.depositMarketUsd(perpsMarketId, msg.sender, amount); + } else { + ITokenModule synth = ITokenModule( + perpsMarketFactory.spotMarket.getSynth(synthMarketId) + ); + synth.transferFrom(msg.sender, address(this), amount); + // depositing into a synth market + perpsMarketFactory.depositMarketCollateral(synth, amount); + } + } + + function _withdrawMargin( + PerpsMarketFactory.Data storage perpsMarketFactory, + uint128 perpsMarketId, + uint128 synthMarketId, + uint256 amount + ) internal { + if (synthMarketId == 0) { + // withdrawing from the USD market + perpsMarketFactory.synthetix.withdrawMarketUsd(perpsMarketId, msg.sender, amount); + } else { + ITokenModule synth = ITokenModule( + perpsMarketFactory.spotMarket.getSynth(synthMarketId) + ); + // withdrawing from a synth market + perpsMarketFactory.synthetix.withdrawMarketCollateral( + perpsMarketId, + address(synth), + amount + ); + synth.transfer(msg.sender, amount); + } + } } diff --git a/markets/perps-market/contracts/modules/PerpsMarketFactoryModule.sol b/markets/perps-market/contracts/modules/PerpsMarketFactoryModule.sol index 833cd6cfda..5f622ebbb8 100644 --- a/markets/perps-market/contracts/modules/PerpsMarketFactoryModule.sol +++ b/markets/perps-market/contracts/modules/PerpsMarketFactoryModule.sol @@ -11,6 +11,7 @@ import {FeatureFlag} from "@synthetixio/core-modules/contracts/storage/FeatureFl import {IERC165} from "@synthetixio/core-contracts/contracts/interfaces/IERC165.sol"; import {DecimalMath} from "@synthetixio/core-contracts/contracts/utils/DecimalMath.sol"; import {PerpsMarketFactory} from "../storage/PerpsMarketFactory.sol"; +import {GlobalPerpsMarket} from "../storage/GlobalPerpsMarket.sol"; import {GlobalPerpsMarketConfiguration} from "../storage/GlobalPerpsMarketConfiguration.sol"; import {PerpsMarket} from "../storage/PerpsMarket.sol"; import {PerpsPrice} from "../storage/PerpsPrice.sol"; @@ -18,6 +19,7 @@ import {IPerpsMarketFactoryModule} from "../interfaces/IPerpsMarketFactoryModule import {ISpotMarketSystem} from "../interfaces/external/ISpotMarketSystem.sol"; import {ISynthetixSystem} from "../interfaces/external/ISynthetixSystem.sol"; import {AddressError} from "@synthetixio/core-contracts/contracts/errors/AddressError.sol"; +import {ParameterError} from "@synthetixio/core-contracts/contracts/errors/ParameterError.sol"; import {MathUtil} from "../utils/MathUtil.sol"; import {PerpsMarketConfiguration} from "../storage/PerpsMarketConfiguration.sol"; import {IMarket} from "@synthetixio/main/contracts/interfaces/external/IMarket.sol"; @@ -28,6 +30,8 @@ import {IMarket} from "@synthetixio/main/contracts/interfaces/external/IMarket.s */ contract PerpsMarketFactoryModule is IPerpsMarketFactoryModule { using AssociatedSystem for AssociatedSystem.Data; + using PerpsMarketFactory for PerpsMarketFactory.Data; + using GlobalPerpsMarket for GlobalPerpsMarket.Data; using PerpsPrice for PerpsPrice.Data; using DecimalMath for uint256; @@ -35,8 +39,6 @@ contract PerpsMarketFactoryModule is IPerpsMarketFactoryModule { bytes32 private constant _ACCOUNT_TOKEN_SYSTEM = "accountNft"; - error InvalidMarketOwner(); - /** * @inheritdoc IPerpsMarketFactoryModule */ @@ -56,40 +58,55 @@ contract PerpsMarketFactoryModule is IPerpsMarketFactoryModule { PerpsMarketFactory.load().spotMarket = spotMarket; } + function initializeFactory() external override returns (uint128) { + FeatureFlag.ensureAccessToFeature(_CREATE_MARKET_FEATURE_FLAG); + OwnableStorage.onlyOwner(); + + PerpsMarketFactory.Data storage factory = PerpsMarketFactory.load(); + + if (factory.perpsMarketId == 0) { + uint128 perpsMarketId = factory.synthetix.registerMarket(address(this)); + factory.perpsMarketId = perpsMarketId; + + emit FactoryInitialized(perpsMarketId); + + return perpsMarketId; + } else { + return factory.perpsMarketId; + } + } + /** * @inheritdoc IPerpsMarketFactoryModule */ function createMarket( + uint128 requestedMarketId, string memory marketName, - string memory marketSymbol, - address marketOwner + string memory marketSymbol ) external override returns (uint128) { - FeatureFlag.ensureAccessToFeature(_CREATE_MARKET_FEATURE_FLAG); + OwnableStorage.onlyOwner(); + PerpsMarketFactory.load().onlyIfInitialized(); - if (marketOwner == address(0)) { - revert InvalidMarketOwner(); + if (requestedMarketId == 0) { + revert ParameterError.InvalidParameter("requestedMarketId", "cannot be 0"); } - PerpsMarketFactory.Data storage store = PerpsMarketFactory.load(); - uint128 perpsMarketId = store.synthetix.registerMarket(address(this)); - - PerpsMarket.create(perpsMarketId, marketOwner, marketName, marketSymbol); + PerpsMarket.createValid(requestedMarketId, marketName, marketSymbol); + GlobalPerpsMarket.load().addMarket(requestedMarketId); - emit MarketRegistered(perpsMarketId, marketOwner, marketName, marketSymbol); + emit MarketCreated(requestedMarketId, marketName, marketSymbol); - return perpsMarketId; + return requestedMarketId; } function name(uint128 perpsMarketId) external view override returns (string memory) { - return string.concat(PerpsMarket.load(perpsMarketId).name, " Perps Market"); - } - - function symbol(uint128 perpsMarketId) external view override returns (string memory) { - return PerpsMarket.load(perpsMarketId).symbol; + // todo: set name on initialize? + return "Perps Market"; } function reportedDebt(uint128 perpsMarketId) external view override returns (uint256) { - return MathUtil.abs(PerpsMarket.load(perpsMarketId).skew); + // TODO + return 0; } function minimumCredit(uint128 perpsMarketId) external view override returns (uint256) { @@ -99,61 +116,6 @@ contract PerpsMarketFactoryModule is IPerpsMarketFactoryModule { ); } - /** - * @inheritdoc IPerpsMarketFactoryModule - */ - function updatePriceData(uint128 perpsMarketId, bytes32 feedId) external override { - PerpsMarket.loadWithVerifiedOwner(perpsMarketId, msg.sender); - - PerpsPrice.load(perpsMarketId).update(feedId); - - emit MarketPriceDataUpdated(perpsMarketId, feedId); - } - - /** - * @inheritdoc IPerpsMarketFactoryModule - */ - function nominateMarketOwner( - uint128 perpsMarketId, - address newNominatedOwner - ) external override { - PerpsMarket.Data storage market = PerpsMarket.loadWithVerifiedOwner( - perpsMarketId, - msg.sender - ); - - if (newNominatedOwner == address(0)) { - revert AddressError.ZeroAddress(); - } - - market.nominatedOwner = newNominatedOwner; - - emit MarketOwnerNominated(perpsMarketId, newNominatedOwner); - } - - /** - * @inheritdoc IPerpsMarketFactoryModule - */ - function acceptMarketOwnership(uint128 perpsMarketId) external override { - PerpsMarket.Data storage market = PerpsMarket.load(perpsMarketId); - address currentNominatedOwner = market.nominatedOwner; - if (msg.sender != currentNominatedOwner) { - revert NotNominated(msg.sender); - } - - emit MarketOwnerChanged(perpsMarketId, market.owner, currentNominatedOwner); - - market.owner = currentNominatedOwner; - market.nominatedOwner = address(0); - } - - /** - * @inheritdoc IPerpsMarketFactoryModule - */ - function getMarketOwner(uint128 perpsMarketId) external view override returns (address) { - return PerpsMarket.load(perpsMarketId).owner; - } - /** * @dev See {IERC165-supportsInterface}. */ diff --git a/markets/perps-market/contracts/modules/PerpsMarketModule.sol b/markets/perps-market/contracts/modules/PerpsMarketModule.sol index c49b4feb70..60e43117d1 100644 --- a/markets/perps-market/contracts/modules/PerpsMarketModule.sol +++ b/markets/perps-market/contracts/modules/PerpsMarketModule.sol @@ -6,11 +6,19 @@ import {PerpsMarketConfiguration} from "../storage/PerpsMarketConfiguration.sol" import {PerpsPrice} from "../storage/PerpsPrice.sol"; import {AsyncOrder} from "../storage/AsyncOrder.sol"; import {IPerpsMarketModule} from "../interfaces/IPerpsMarketModule.sol"; +import {AddressError} from "@synthetixio/core-contracts/contracts/errors/AddressError.sol"; contract PerpsMarketModule is IPerpsMarketModule { using PerpsMarket for PerpsMarket.Data; using AsyncOrder for AsyncOrder.Data; + function metadata( + uint128 marketId + ) external view override returns (string memory name, string memory symbol) { + PerpsMarket.Data storage market = PerpsMarket.load(marketId); + return (market.name, market.symbol); + } + function skew(uint128 marketId) external view override returns (int256) { return PerpsMarket.load(marketId).skew; } diff --git a/markets/perps-market/contracts/storage/GlobalPerpsMarket.sol b/markets/perps-market/contracts/storage/GlobalPerpsMarket.sol index 3aecf7df64..e0f0fe36a2 100644 --- a/markets/perps-market/contracts/storage/GlobalPerpsMarket.sol +++ b/markets/perps-market/contracts/storage/GlobalPerpsMarket.sol @@ -4,14 +4,19 @@ pragma solidity >=0.8.11 <0.9.0; import {SetUtil} from "@synthetixio/core-contracts/contracts/utils/SetUtil.sol"; import {MathUtil} from "../utils/MathUtil.sol"; import {GlobalPerpsMarketConfiguration} from "./GlobalPerpsMarketConfiguration.sol"; -import {SafeCastI256} from "@synthetixio/core-contracts/contracts/utils/SafeCast.sol"; +import {SafeCastU256, SafeCastI256, SafeCastU128} from "@synthetixio/core-contracts/contracts/utils/SafeCast.sol"; import {PerpsAccount} from "./PerpsAccount.sol"; +import {PerpsMarketFactory} from "./PerpsMarketFactory.sol"; +import {PerpsPrice} from "./PerpsPrice.sol"; +import {ISpotMarketSystem} from "../interfaces/external/ISpotMarketSystem.sol"; /* Note: This library contains all global perps market data */ library GlobalPerpsMarket { using SafeCastI256 for int256; + using SafeCastU256 for uint256; + using SafeCastU128 for uint128; using SetUtil for SetUtil.UintSet; bytes32 private constant _SLOT_GLOBAL_PERPS_MARKET = @@ -30,6 +35,8 @@ library GlobalPerpsMarket { SetUtil.UintSet liquidatableAccounts; // collateral amounts running total mapping(uint128 => uint) collateralAmounts; + SetUtil.UintSet activeCollateralTypes; + SetUtil.UintSet activeMarkets; } function load() internal pure returns (Data storage marketData) { @@ -39,6 +46,41 @@ library GlobalPerpsMarket { } } + function totalCollateralValue(Data storage self) internal view returns (uint256 total) { + ISpotMarketSystem spotMarket = PerpsMarketFactory.load().spotMarket; + SetUtil.UintSet storage activeCollateralTypes = self.activeCollateralTypes; + uint256 activeCollateralLength = activeCollateralTypes.length(); + for (uint i = 1; i < activeCollateralLength; i++) { + uint128 synthMarketId = activeCollateralTypes.valueAt(i).to128(); + + if (synthMarketId == 0) { + total += self.collateralAmounts[synthMarketId]; + } else { + (uint collateralValue, ) = spotMarket.quoteSellExactIn( + synthMarketId, + self.collateralAmounts[synthMarketId] + ); + total += collateralValue; + } + } + } + + function updateCollateralAmount( + Data storage self, + uint128 synthMarketId, + int amountDelta + ) internal returns (uint collateralAmount) { + collateralAmount = (self.collateralAmounts[synthMarketId].toInt() + amountDelta).toUint(); + self.collateralAmounts[synthMarketId] = collateralAmount; + + bool isActiveCollateral = self.activeCollateralTypes.contains(synthMarketId); + if (collateralAmount > 0 && !isActiveCollateral) { + self.activeCollateralTypes.add(synthMarketId.to256()); + } else if (collateralAmount == 0 && isActiveCollateral) { + self.activeCollateralTypes.remove(synthMarketId.to256()); + } + } + function checkLiquidation(Data storage self, uint128 accountId) internal view { if (self.liquidatableAccounts.contains(accountId)) { revert PerpsAccount.AccountLiquidatable(accountId); @@ -49,11 +91,11 @@ library GlobalPerpsMarket { 1. checks to ensure max cap isn't hit 2. adjusts accounting for collateral amounts */ - function checkCollateralAmountAndAdjust( + function validateCollateralAmount( Data storage self, uint128 synthMarketId, int synthAmount - ) internal { + ) internal view { uint collateralAmount = self.collateralAmounts[synthMarketId]; if (synthAmount > 0) { uint maxAmount = GlobalPerpsMarketConfiguration.load().maxCollateralAmounts[ @@ -70,16 +112,16 @@ library GlobalPerpsMarket { collateralAmount, synthAmount.toUint() ); - } else { - self.collateralAmounts[synthMarketId] += synthAmount.toUint(); } } else { uint synthAmountAbs = MathUtil.abs(synthAmount); if (collateralAmount < synthAmountAbs) { revert InsufficientCollateral(synthMarketId, collateralAmount, synthAmountAbs); } - - self.collateralAmounts[synthMarketId] -= MathUtil.abs(synthAmount); } } + + function addMarket(Data storage self, uint128 marketId) internal { + self.activeMarkets.add(marketId.to256()); + } } diff --git a/markets/perps-market/contracts/storage/PerpsAccount.sol b/markets/perps-market/contracts/storage/PerpsAccount.sol index c71462edf3..d25d393932 100644 --- a/markets/perps-market/contracts/storage/PerpsAccount.sol +++ b/markets/perps-market/contracts/storage/PerpsAccount.sol @@ -30,6 +30,7 @@ library PerpsAccount { using PerpsMarket for PerpsMarket.Data; using PerpsMarketConfiguration for PerpsMarketConfiguration.Data; using PerpsMarketFactory for PerpsMarketFactory.Data; + using GlobalPerpsMarket for GlobalPerpsMarket.Data; using GlobalPerpsMarketConfiguration for GlobalPerpsMarketConfiguration.Data; using DecimalMath for int256; using DecimalMath for uint256; @@ -59,6 +60,16 @@ library PerpsAccount { } } + /** + @notice allows us to update the account id in case it needs to be + */ + function create(uint128 id) internal returns (Data storage account) { + account = load(id); + if (account.id == 0) { + account.id = id; + } + } + function isEligibleForLiquidation( Data storage self ) @@ -85,15 +96,15 @@ library PerpsAccount { } } - function updatePositionMarkets(Data storage self, uint positionMarketId, int size) internal { - if (size == 0) { + function updateOpenPositions(Data storage self, uint positionMarketId, int size) internal { + if (size == 0 && self.openPositionMarketIds.contains(positionMarketId)) { self.openPositionMarketIds.remove(positionMarketId); } else if (!self.openPositionMarketIds.contains(positionMarketId)) { self.openPositionMarketIds.add(positionMarketId); } } - function checkPendingOrder(Data storage self) internal { + function checkPendingOrder(Data storage self) internal view { // Check if there are pending orders AsyncOrder.Data memory asyncOrder = AsyncOrder.load(self.id); if (asyncOrder.sizeDelta != 0) { @@ -101,36 +112,30 @@ library PerpsAccount { } } - function addCollateralAmount( + function updateCollateralAmount( Data storage self, uint128 synthMarketId, - uint amountToAdd - ) internal { - if (!self.activeCollateralTypes.contains(synthMarketId)) { - self.activeCollateralTypes.add(synthMarketId); - } + int amountDelta + ) internal returns (uint256 collateralAmount) { + collateralAmount = (self.collateralAmounts[synthMarketId].toInt() + amountDelta).toUint(); + self.collateralAmounts[synthMarketId] = collateralAmount; - self.collateralAmounts[synthMarketId] += amountToAdd; - } - - // TODO: rename this maybe? not really withdrawing collateral, just accounting - function removeCollateralAmount( - Data storage self, - uint128 synthMarketId, - uint amountToRemove - ) internal { - self.collateralAmounts[synthMarketId] -= amountToRemove; - - if (self.collateralAmounts[synthMarketId] == 0) { + bool isActiveCollateral = self.activeCollateralTypes.contains(synthMarketId); + if (collateralAmount > 0 && !isActiveCollateral) { + self.activeCollateralTypes.add(synthMarketId); + } else if (collateralAmount == 0 && isActiveCollateral) { self.activeCollateralTypes.remove(synthMarketId); } + + // always update global values when account collateral is changed + GlobalPerpsMarket.load().updateCollateralAmount(synthMarketId, amountDelta); } /** * @notice This function validates you have enough margin to withdraw without being liquidated. * @dev This is done by checking your collateral value against your margin maintenance value. */ - function checkAvailableWithdrawableValue( + function validateWithdrawableAmount( Data storage self, uint256 amountToWithdraw ) internal view returns (uint256 availableWithdrawableCollateralUsd) { @@ -232,18 +237,23 @@ library PerpsAccount { } function convertAllCollateralToUsd(Data storage self) internal { - for (uint i = 1; i < self.activeCollateralTypes.length(); i++) { - uint128 synthMarketId = self.activeCollateralTypes.valueAt(i).to128(); + PerpsMarketFactory.Data storage factory = PerpsMarketFactory.load(); + SetUtil.UintSet storage activeCollateralTypes = self.activeCollateralTypes; + uint256 activeCollateralTypesLength = activeCollateralTypes.length(); + + // 1. withdraw all collateral from synthetix + // 2. sell all collateral for snxUSD + // 3. deposit snxUSD into synthetix + for (uint i = 1; i <= activeCollateralTypesLength; i++) { + uint128 synthMarketId = activeCollateralTypes.valueAt(i).to128(); if (synthMarketId != SNX_USD_MARKET_ID) { - uint amount = self.collateralAmounts[synthMarketId]; - // TODO what do we use for referer here/ min amount? - (uint amountSold, ) = PerpsMarketFactory.load().spotMarket.sellExactIn( + _deductAllSynth(self, factory, synthMarketId); + } else { + updateCollateralAmount( + self, synthMarketId, - amount, - 0, - address(0) + -(self.collateralAmounts[synthMarketId].toInt()) ); - self.collateralAmounts[SNX_USD_MARKET_ID] += amountSold; } } } @@ -252,11 +262,12 @@ library PerpsAccount { Data storage self, uint amount // snxUSD ) internal { - // TODO: deduct from snxUSD first? uint leftoverAmount = amount; uint128[] storage synthDeductionPriority = GlobalPerpsMarketConfiguration .load() .synthDeductionPriority; + ISpotMarketSystem spotMarket = PerpsMarketFactory.load().spotMarket; + PerpsMarketFactory.Data storage factory = PerpsMarketFactory.load(); for (uint i = 0; i < synthDeductionPriority.length; i++) { uint128 marketId = synthDeductionPriority[i]; uint availableAmount = self.collateralAmounts[marketId]; @@ -267,42 +278,56 @@ library PerpsAccount { if (marketId == SNX_USD_MARKET_ID) { // snxUSD if (availableAmount >= leftoverAmount) { - removeCollateralAmount(self, marketId, leftoverAmount); + updateCollateralAmount(self, marketId, -(leftoverAmount.toInt())); leftoverAmount = 0; break; } else { - removeCollateralAmount(self, marketId, availableAmount); + updateCollateralAmount(self, marketId, -(availableAmount.toInt())); leftoverAmount -= availableAmount; } } else { - // TODO: check if market is paused; if not, continue - ISpotMarketSystem spotMarket = PerpsMarketFactory.load().spotMarket; - (uint availableAmountUsd, ) = spotMarket.quoteSellExactIn( + (uint synthAmountRequired, ) = spotMarket.quoteSellExactOut( marketId, - availableAmount + leftoverAmount ); - if (availableAmountUsd >= leftoverAmount) { - // TODO referer/max amt + address synthToken = factory.spotMarket.getSynth(marketId); + + if (availableAmount >= synthAmountRequired) { + factory.synthetix.withdrawMarketCollateral( + factory.perpsMarketId, + synthToken, + synthAmountRequired + ); + (uint amountToDeduct, ) = spotMarket.sellExactOut( marketId, leftoverAmount, type(uint).max, address(0) ); - removeCollateralAmount(self, marketId, amountToDeduct); + // TODO: deposit snxUSD + + updateCollateralAmount(self, marketId, -(amountToDeduct.toInt())); leftoverAmount = 0; break; } else { - // TODO referer - (uint amountToDeduct, ) = spotMarket.sellExactIn( + factory.synthetix.withdrawMarketCollateral( + factory.perpsMarketId, + synthToken, + availableAmount + ); + + (uint amountToDeductUsd, ) = spotMarket.sellExactIn( marketId, availableAmount, 0, address(0) ); - removeCollateralAmount(self, marketId, availableAmount); - leftoverAmount -= amountToDeduct; + // TODO: deposit snxUSD + + updateCollateralAmount(self, marketId, -(availableAmount.toInt())); + leftoverAmount -= amountToDeductUsd; } } } @@ -312,154 +337,37 @@ library PerpsAccount { } } - struct RuntimeLiquidationData { - uint totalLosingPnl; - uint accumulatedLiquidationRewards; - uint liquidationReward; - uint losingMarketsLength; - uint profitableMarketsLength; - uint128[] profitableMarkets; - uint128[] losingMarkets; - uint amountToDeposit; - uint amountToLiquidateRatioD18; - uint totalLosingPnlRatioD18; - uint totalAvailableForDeposit; - } - - function liquidateAccount( - Data storage self - ) internal returns (bool fullLiquidation, uint256 reward) { - RuntimeLiquidationData memory runtime; - runtime.profitableMarkets = new uint128[](self.openPositionMarketIds.length()); - runtime.losingMarkets = new uint128[](self.openPositionMarketIds.length()); - - fullLiquidation = true; - - // loop through all positions - // split into profitable / unprofitable - for (uint i = 1; i <= self.openPositionMarketIds.length(); i++) { - uint128 positionMarketId = self.openPositionMarketIds.valueAt(i).to128(); - Position.Data storage position = PerpsMarket.load(positionMarketId).positions[self.id]; - - uint price = PerpsPrice.getCurrentPrice(positionMarketId); - - (int totalPnl, , , ) = position.getPnl(price); - - if (totalPnl > 0) { - runtime.profitableMarkets[runtime.profitableMarketsLength] = positionMarketId; - runtime.profitableMarketsLength++; - } else { - runtime.losingMarkets[runtime.losingMarketsLength] = positionMarketId; - runtime.losingMarketsLength++; - runtime.totalLosingPnl += MathUtil.abs(totalPnl); - } - } - - // loop over profitable - // close position if you can (maxLiquidatableValue) - // withdraw from market keeper fee based on pnl that was liquidated - // If any position is open after _processMarketLiquidation, set fullLiquidation to false since it's not a partial liquidation. - PerpsMarketFactory.Data storage factory = PerpsMarketFactory.load(); - for (uint i = 0; i < runtime.profitableMarketsLength; i++) { - uint128 positionMarketId = runtime.profitableMarkets[i]; - (, int totalPnl, uint liquidationReward, ) = _processMarketLiquidation( - self, - positionMarketId - ); - - if (self.openPositionMarketIds.contains(positionMarketId)) { - // partial liquidation - fullLiquidation = false; - } - - // withdraw from market - uint256 amountToWithdraw = totalPnl.toUint() + liquidationReward; - factory.synthetix.withdrawMarketUsd(positionMarketId, address(this), amountToWithdraw); - self.collateralAmounts[SNX_USD_MARKET_ID] += amountToWithdraw - liquidationReward; - - runtime.accumulatedLiquidationRewards += liquidationReward; - } - - // if all profitable positions are closed, then proceed to losing positions. - // waiting for all profitable markets to be fully closed is required to ensure - // we accrue all snxUSD before closing out losing positions - if (fullLiquidation) { - uint totalAvailableUsd = self.collateralAmounts[SNX_USD_MARKET_ID]; - - // loop over losing positions, - // -- in loop - /* - 1. get the loss amount - 2. loss = find the min of loss, max liquidatable - 3. % = (loss * pnl) / all losing positions pnl - 4. colateral balance * % = value to deposit for that market - */ - // --- - - for (uint i = 0; i < runtime.losingMarketsLength; i++) { - uint128 positionMarketId = runtime.losingMarkets[i]; - ( - uint amountToLiquidate, - int totalPnl, - uint liquidationReward, - int128 oldPositionSize - ) = _processMarketLiquidation(self, positionMarketId); - - if (self.openPositionMarketIds.contains(positionMarketId)) { - // partial liquidation - fullLiquidation = false; - } + function liquidateAccount(Data storage self) internal returns (uint256 reward) { + SetUtil.UintSet storage openPositionMarketIds = self.openPositionMarketIds; + uint256 openPositionsLength = openPositionMarketIds.length(); - if (amountToLiquidate == 0) { - continue; - } - - runtime.amountToLiquidateRatioD18 = amountToLiquidate.divDecimal( - MathUtil.abs(oldPositionSize) - ); - - runtime.totalLosingPnlRatioD18 = MathUtil.abs(totalPnl).divDecimal( - runtime.totalLosingPnl - ); - runtime.totalAvailableForDeposit = totalAvailableUsd.mulDecimal( - runtime.totalLosingPnlRatioD18 - ); - - runtime.amountToDeposit = runtime.totalAvailableForDeposit.mulDecimal( - runtime.amountToLiquidateRatioD18 - ); + uint accumulatedLiquidationRewards; - runtime.amountToDeposit -= liquidationReward; - runtime.accumulatedLiquidationRewards += liquidationReward; + for (uint i = 1; i <= openPositionsLength; i++) { + uint128 positionMarketId = openPositionMarketIds.valueAt(i).to128(); + PerpsMarket.Data storage perpsMarket = PerpsMarket.load(positionMarketId); + Position.Data storage position = perpsMarket.positions[self.id]; - factory.depositToMarketManager(positionMarketId, runtime.amountToDeposit); - self.collateralAmounts[SNX_USD_MARKET_ID] -= runtime.amountToDeposit; - } + (, , uint liquidationReward, ) = _liquidatePosition(self, positionMarketId, position); + accumulatedLiquidationRewards += liquidationReward; } - reward = _processLiquidationRewards(factory, runtime.accumulatedLiquidationRewards); + reward = _processLiquidationRewards(accumulatedLiquidationRewards); } - function _processLiquidationRewards( - PerpsMarketFactory.Data storage factory, - uint256 totalRewards - ) private returns (uint256 reward) { + function _processLiquidationRewards(uint256 totalRewards) private returns (uint256 reward) { // pay out liquidation rewards reward = GlobalPerpsMarketConfiguration.load().liquidationReward(totalRewards); - - // TODO: handle this scenario - // if (totalRewards > reward) { - // // if leftover rewards, return to LPs (market manager) - // // send to fee collector - // } if (reward > 0) { - factory.usdToken.transfer(msg.sender, reward); + PerpsMarketFactory.Data storage factory = PerpsMarketFactory.load(); + factory.synthetix.withdrawMarketUsd(factory.perpsMarketId, msg.sender, reward); } } - function _processMarketLiquidation( + function _liquidatePosition( Data storage self, - uint128 positionMarketId + uint128 marketId, + Position.Data storage position ) private returns ( @@ -469,12 +377,11 @@ library PerpsAccount { int128 oldPositionSize ) { - PerpsMarket.Data storage perpsMarket = PerpsMarket.load(positionMarketId); - Position.Data storage position = perpsMarket.positions[self.id]; + PerpsMarket.Data storage perpsMarket = PerpsMarket.load(marketId); oldPositionSize = position.size; amountToLiquidate = perpsMarket.maxLiquidatableAmount(MathUtil.abs(oldPositionSize)); - uint price = PerpsPrice.getCurrentPrice(positionMarketId); + uint price = PerpsPrice.getCurrentPrice(marketId); (, totalPnl, , , ) = position.getPositionData(price); @@ -485,11 +392,40 @@ library PerpsAccount { : oldPositionSize + amtToLiquidationInt; // update position markets - updatePositionMarkets(self, positionMarketId, position.size); + updateOpenPositions(self, marketId, position.size); + + // update market data + perpsMarket.updateMarketSizes(oldPositionSize, position.size); // using amountToLiquidate to calculate liquidation reward (, , , , liquidationReward) = PerpsMarketConfiguration - .load(positionMarketId) + .load(marketId) .calculateRequiredMargins(amtToLiquidationInt, price); } + + function _deductAllSynth( + Data storage self, + PerpsMarketFactory.Data storage factory, + uint128 synthMarketId + ) private { + uint amount = self.collateralAmounts[synthMarketId]; + address synth = factory.spotMarket.getSynth(synthMarketId); + + // 1. withdraw collateral from market manager + factory.synthetix.withdrawMarketCollateral(factory.perpsMarketId, synth, amount); + + // 2. sell collateral for snxUSD + (uint amountUsd, ) = PerpsMarketFactory.load().spotMarket.sellExactIn( + synthMarketId, + amount, + 0, + address(0) + ); + + // 3. deposit snxUSD into market manager + factory.synthetix.depositMarketUsd(factory.perpsMarketId, address(this), amountUsd); + + // 4. update account collateral amount + updateCollateralAmount(self, synthMarketId, -(amount.toInt())); + } } diff --git a/markets/perps-market/contracts/storage/PerpsMarket.sol b/markets/perps-market/contracts/storage/PerpsMarket.sol index 7a16f15ebe..b759e25492 100644 --- a/markets/perps-market/contracts/storage/PerpsMarket.sol +++ b/markets/perps-market/contracts/storage/PerpsMarket.sol @@ -24,21 +24,18 @@ library PerpsMarket { using Position for Position.Data; using PerpsMarketConfiguration for PerpsMarketConfiguration.Data; - error OnlyMarketOwner(address marketOwner, address sender); - error InvalidMarket(uint128 marketId); error PriceFeedNotSet(uint128 marketId); + error MarketAlreadyExists(uint128 marketId); + struct Data { - address owner; - address nominatedOwner; string name; string symbol; uint128 id; int256 skew; uint256 size; - // TODO: move to new data structure? int lastFundingRate; int lastFundingValue; uint256 lastFundingTime; @@ -49,33 +46,36 @@ library PerpsMarket { mapping(uint => Position.Data) positions; } - function create( + function load(uint128 marketId) internal pure returns (Data storage market) { + bytes32 s = keccak256(abi.encode("io.synthetix.perps-market.PerpsMarket", marketId)); + + assembly { + market.slot := s + } + } + + function createValid( uint128 id, - address owner, string memory name, string memory symbol ) internal returns (Data storage market) { + if (id == 0 || load(id).id == id) { + revert InvalidMarket(id); + } + market = load(id); + market.id = id; - market.owner = owner; market.name = name; market.symbol = symbol; } - function load(uint128 marketId) internal pure returns (Data storage market) { - bytes32 s = keccak256(abi.encode("io.synthetix.perps-market.PerpsMarket", marketId)); - - assembly { - market.slot := s - } - } - /** * @dev Reverts if the market does not exist with appropriate error. Otherwise, returns the market. */ function loadValid(uint128 marketId) internal view returns (Data storage market) { market = load(marketId); - if (market.owner == address(0)) { + if (market.id == 0) { revert InvalidMarket(marketId); } @@ -84,13 +84,6 @@ library PerpsMarket { } } - // TODO: can remove and use loadWithVerifiedOwner - function onlyMarketOwner(Data storage self) internal view { - if (self.owner != msg.sender) { - revert OnlyMarketOwner(self.owner, msg.sender); - } - } - /** * @dev Returns the max amount of liquidation that can occur based on the market configuration * @notice Based on the configured liquidation window, a trader can only be liquidated for a certain @@ -150,8 +143,7 @@ library PerpsMarket { Position.Data storage oldPosition = self.positions[accountId]; int128 oldPositionSize = oldPosition.size; - self.size = (self.size + MathUtil.abs(newPosition.size)) - MathUtil.abs(oldPositionSize); - self.skew += newPosition.size - oldPositionSize; + updateMarketSizes(self, newPosition.size, oldPositionSize); oldPosition.updatePosition(newPosition); // TODO add current market debt return @@ -164,15 +156,13 @@ library PerpsMarket { ); } - function loadWithVerifiedOwner( - uint128 id, - address possibleOwner - ) internal view returns (Data storage market) { - market = load(id); - - if (market.owner != possibleOwner) { - revert AccessError.Unauthorized(possibleOwner); - } + function updateMarketSizes( + Data storage self, + int128 newPositionSize, + int128 oldPositionSize + ) internal { + self.size = (self.size + MathUtil.abs(newPositionSize)) - MathUtil.abs(oldPositionSize); + self.skew += newPositionSize - oldPositionSize; } function recomputeFunding( diff --git a/markets/perps-market/contracts/storage/PerpsMarketFactory.sol b/markets/perps-market/contracts/storage/PerpsMarketFactory.sol index cec263072f..3979a1c6a6 100644 --- a/markets/perps-market/contracts/storage/PerpsMarketFactory.sol +++ b/markets/perps-market/contracts/storage/PerpsMarketFactory.sol @@ -4,7 +4,7 @@ pragma solidity >=0.8.11 <0.9.0; import {ITokenModule} from "@synthetixio/core-modules/contracts/interfaces/ITokenModule.sol"; import {INodeModule} from "@synthetixio/oracle-manager/contracts/interfaces/INodeModule.sol"; import {IMarketCollateralModule} from "@synthetixio/main/contracts/interfaces/IMarketCollateralModule.sol"; - +import {AccessError} from "@synthetixio/core-contracts/contracts/errors/AccessError.sol"; import {ISynthetixSystem} from "../interfaces/external/ISynthetixSystem.sol"; import {ISpotMarketSystem} from "../interfaces/external/ISpotMarketSystem.sol"; @@ -15,7 +15,8 @@ library PerpsMarketFactory { bytes32 private constant _SLOT_PERPS_MARKET_FACTORY = keccak256(abi.encode("io.synthetix.perps-market.PerpsMarketFactory")); - error OnlyMarketOwner(address marketOwner, address sender); + error PerpsMarketNotInitialized(); + error PerpsMarketAlreadyInitialized(); struct Data { /** @@ -28,6 +29,21 @@ library PerpsMarketFactory { */ ISynthetixSystem synthetix; ISpotMarketSystem spotMarket; + uint128 perpsMarketId; + address owner; + address nominatedOwner; + } + + function onlyIfInitialized(Data storage self) internal view { + if (self.perpsMarketId == 0) { + revert PerpsMarketNotInitialized(); + } + } + + function onlyIfNotInitialized(Data storage self) internal view { + if (self.perpsMarketId != 0) { + revert PerpsMarketAlreadyInitialized(); + } } function load() internal pure returns (Data storage perpsMarketFactory) { @@ -37,6 +53,15 @@ library PerpsMarketFactory { } } + function depositMarketCollateral( + Data storage self, + ITokenModule collateral, + uint256 amount + ) internal { + collateral.approve(address(self.synthetix), amount); + self.synthetix.depositMarketCollateral(self.perpsMarketId, address(collateral), amount); + } + function depositToMarketManager(Data storage self, uint128 marketId, uint256 amount) internal { self.usdToken.approve(address(this), amount); self.synthetix.depositMarketUsd(marketId, address(this), amount); diff --git a/markets/perps-market/storage.dump.sol b/markets/perps-market/storage.dump.sol index 66c6e48d88..c5d93f6943 100644 --- a/markets/perps-market/storage.dump.sol +++ b/markets/perps-market/storage.dump.sol @@ -424,8 +424,9 @@ interface IAsyncOrderSettlementModule { int128 sizeDelta; int256 pnl; uint256 pnlUint; - uint256 amountToDeposit; + uint256 amountToDeduct; uint256 settlementReward; + PerpsMarketFactory.Data factory; } } @@ -514,6 +515,8 @@ library GlobalPerpsMarket { struct Data { SetUtil.UintSet liquidatableAccounts; mapping(uint128 => uint) collateralAmounts; + SetUtil.UintSet activeCollateralTypes; + SetUtil.UintSet activeMarkets; } function load() internal pure returns (Data storage marketData) { bytes32 s = _SLOT_GLOBAL_PERPS_MARKET; @@ -556,19 +559,6 @@ library PerpsAccount { SetUtil.UintSet activeCollateralTypes; SetUtil.UintSet openPositionMarketIds; } - struct RuntimeLiquidationData { - uint totalLosingPnl; - uint accumulatedLiquidationRewards; - uint liquidationReward; - uint losingMarketsLength; - uint profitableMarketsLength; - uint128[] profitableMarkets; - uint128[] losingMarkets; - uint amountToDeposit; - uint amountToLiquidateRatioD18; - uint totalLosingPnlRatioD18; - uint totalAvailableForDeposit; - } function load(uint128 id) internal pure returns (Data storage account) { bytes32 s = keccak256(abi.encode("io.synthetix.perps-market.Account", id)); assembly { @@ -580,8 +570,6 @@ library PerpsAccount { // @custom:artifact contracts/storage/PerpsMarket.sol:PerpsMarket library PerpsMarket { struct Data { - address owner; - address nominatedOwner; string name; string symbol; uint128 id; @@ -641,6 +629,9 @@ library PerpsMarketFactory { address usdToken; address synthetix; address spotMarket; + uint128 perpsMarketId; + address owner; + address nominatedOwner; } function load() internal pure returns (Data storage perpsMarketFactory) { bytes32 s = _SLOT_PERPS_MARKET_FACTORY; diff --git a/markets/perps-market/test/integration/Account/ModifyCollateral.deposit.test.ts b/markets/perps-market/test/integration/Account/ModifyCollateral.deposit.test.ts index 0828a178e3..1c248bdda4 100644 --- a/markets/perps-market/test/integration/Account/ModifyCollateral.deposit.test.ts +++ b/markets/perps-market/test/integration/Account/ModifyCollateral.deposit.test.ts @@ -8,7 +8,7 @@ describe('ModifyCollateral Deposit', () => { const oneBTC = bn(1); const marginAmount = bn(10_000); - const { systems, owner, synthMarkets, trader1 } = bootstrapMarkets({ + const { systems, owner, superMarketId, synthMarkets, trader1 } = bootstrapMarkets({ synthMarkets: [ { name: 'Bitcoin', @@ -34,7 +34,6 @@ describe('ModifyCollateral Deposit', () => { describe('deposit by modifyCollateral()', async () => { let spotBalanceBefore: ethers.BigNumber; - let perpsBalanceBefore: ethers.BigNumber; let modifyCollateralTxn: ethers.providers.TransactionResponse; before('owner sets limits to max', async () => { @@ -54,11 +53,6 @@ describe('ModifyCollateral Deposit', () => { .synth() .connect(trader1()) .balanceOf(await trader1().getAddress()); - - perpsBalanceBefore = await synthMarkets()[0] - .synth() - .connect(trader1()) - .balanceOf(systems().PerpsMarket.address); }); before('trader1 approves the perps market', async () => { @@ -92,12 +86,13 @@ describe('ModifyCollateral Deposit', () => { assertBn.equal(spotBalanceAfter, spotBalanceBefore.sub(oneBTC)); }); - it('properly reflects the perps market balance', async () => { - const perpsBalanceAfter = await synthMarkets()[0] - .synth() - .connect(trader1()) - .balanceOf(systems().PerpsMarket.address); - assertBn.equal(perpsBalanceAfter, perpsBalanceBefore.add(oneBTC)); + it('properly reflects core system collateral balance', async () => { + const btcCollateralValue = await systems().Core.getMarketCollateralAmount( + superMarketId(), + synthMarkets()[0].synthAddress() + ); + + assertBn.equal(btcCollateralValue, oneBTC); }); it('emits correct event with the expected values', async () => { diff --git a/markets/perps-market/test/integration/Account/ModifyCollateral.withdraw.test.ts b/markets/perps-market/test/integration/Account/ModifyCollateral.withdraw.test.ts index 6841c6b409..81a2a97999 100644 --- a/markets/perps-market/test/integration/Account/ModifyCollateral.withdraw.test.ts +++ b/markets/perps-market/test/integration/Account/ModifyCollateral.withdraw.test.ts @@ -17,7 +17,7 @@ describe('ModifyCollateral Withdraw', () => { const withdrawAmount = wei(0.1); const BTC_PRICE = wei(10_000); - const { systems, owner, synthMarkets, trader1 } = bootstrapMarkets({ + const { systems, owner, synthMarkets, superMarketId, trader1 } = bootstrapMarkets({ synthMarkets: [ { name: 'Bitcoin', @@ -37,7 +37,6 @@ describe('ModifyCollateral Withdraw', () => { describe('withdraw without open position modifyCollateral()', async () => { let spotBalanceBefore: ethers.BigNumber; - let perpsBalanceBefore: ethers.BigNumber; let modifyCollateralWithdrawTxn: ethers.providers.TransactionResponse; before('owner sets limits to max', async () => { @@ -57,11 +56,6 @@ describe('ModifyCollateral Withdraw', () => { .synth() .connect(trader1()) .balanceOf(await trader1().getAddress()); - - perpsBalanceBefore = await synthMarkets()[0] - .synth() - .connect(trader1()) - .balanceOf(systems().PerpsMarket.address); }); before('trader1 approves the perps market', async () => { @@ -98,15 +92,23 @@ describe('ModifyCollateral Withdraw', () => { ); }); - it('properly reflects the perps market balance', async () => { - const perpsBalanceAfter = await synthMarkets()[0] - .synth() - .connect(trader1()) - .balanceOf(systems().PerpsMarket.address); - assertBn.equal( - perpsBalanceAfter, - wei(perpsBalanceBefore).add(depositAmount).sub(withdrawAmount).toBN() + it('properly reflects core system collateral balance', async () => { + // const perpsBalanceAfter = await synthMarkets()[0] + // .synth() + // .connect(trader1()) + // .balanceOf(systems().PerpsMarket.address); + + const btcCollateralValue = await systems().Core.getMarketCollateralAmount( + superMarketId(), + synthMarkets()[0].synthAddress() ); + + assertBn.equal(btcCollateralValue, depositAmount.sub(withdrawAmount).toBN()); + + // assertBn.equal( + // perpsBalanceAfter, + // wei(perpsBalanceBefore).add(depositAmount).sub(withdrawAmount).toBN() + // ); }); it('emits correct event with the expected values', async () => { @@ -122,6 +124,7 @@ describe('ModifyCollateral Withdraw', () => { describe('withdraw with open positions', () => { const perpsMarketConfigs = [ { + requestedMarketId: 25, name: 'Bitcoin', token: 'BTC', price: bn(30_000), @@ -139,6 +142,7 @@ describe('ModifyCollateral Withdraw', () => { }, }, { + requestedMarketId: 26, name: 'Ether', token: 'ETH', price: bn(2000), diff --git a/markets/perps-market/test/integration/Liquidation/Liquidation.margin.test.ts b/markets/perps-market/test/integration/Liquidation/Liquidation.margin.test.ts index c175dfdc87..fefa5c2fef 100644 --- a/markets/perps-market/test/integration/Liquidation/Liquidation.margin.test.ts +++ b/markets/perps-market/test/integration/Liquidation/Liquidation.margin.test.ts @@ -7,6 +7,7 @@ import { snapshotCheckpoint } from '@synthetixio/core-utils/utils/mocha/snapshot describe('Liquidation - margin', async () => { const perpsMarketConfigs = [ { + requestedMarketId: 50, name: 'Bitcoin', token: 'BTC', price: bn(30_000), @@ -24,6 +25,7 @@ describe('Liquidation - margin', async () => { }, }, { + requestedMarketId: 51, name: 'Ether', token: 'ETH', price: bn(2000), @@ -41,6 +43,7 @@ describe('Liquidation - margin', async () => { }, }, { + requestedMarketId: 52, name: 'Link', token: 'LINK', price: bn(5), @@ -58,6 +61,7 @@ describe('Liquidation - margin', async () => { }, }, { + requestedMarketId: 53, name: 'Arbitrum', token: 'ARB', price: bn(2), @@ -75,6 +79,7 @@ describe('Liquidation - margin', async () => { }, }, { + requestedMarketId: 54, name: 'Optimism', token: 'OP', price: bn(2), @@ -93,7 +98,7 @@ describe('Liquidation - margin', async () => { }, ]; - const { systems, provider, trader1, perpsMarkets, marketOwner } = bootstrapMarkets({ + const { systems, provider, trader1, perpsMarkets, owner } = bootstrapMarkets({ synthMarkets: [], perpsMarkets: perpsMarketConfigs, traderAccountIds: [2, 3], @@ -258,7 +263,7 @@ describe('Liquidation - margin', async () => { const maxSecondsInLiquidationWindow = bn(10); const minimumPositionMargin = bn(50); // this is the only change from the initial values await systems() - .PerpsMarket.connect(marketOwner()) + .PerpsMarket.connect(owner()) .setLiquidationParameters( opMarketId, initialMarginFraction, diff --git a/markets/perps-market/test/integration/Liquidation/Liquidation.maxLiquidationAmount.test.ts b/markets/perps-market/test/integration/Liquidation/Liquidation.maxLiquidationAmount.test.ts index ff8770dfa4..89a4f21a01 100644 --- a/markets/perps-market/test/integration/Liquidation/Liquidation.maxLiquidationAmount.test.ts +++ b/markets/perps-market/test/integration/Liquidation/Liquidation.maxLiquidationAmount.test.ts @@ -9,6 +9,7 @@ describe('Liquidation - max liquidatable amount', async () => { synthMarkets: [], perpsMarkets: [ { + requestedMarketId: 50, name: 'Optimism', token: 'OP', price: bn(10), diff --git a/markets/perps-market/test/integration/Market/CreateMarket.test.ts b/markets/perps-market/test/integration/Market/CreateMarket.test.ts index fd465fe2c5..c3313f247e 100644 --- a/markets/perps-market/test/integration/Market/CreateMarket.test.ts +++ b/markets/perps-market/test/integration/Market/CreateMarket.test.ts @@ -1,4 +1,4 @@ -import { ethers } from 'ethers'; +import { ethers, BigNumber } from 'ethers'; import { bn, bootstrapMarkets } from '../bootstrap'; import assert from 'assert'; import assertRevert from '@synthetixio/core-utils/utils/assertions/assert-revert'; @@ -11,75 +11,47 @@ describe('Create Market test', () => { token = 'snxETH', price = bn(1000); - const { systems, signers, owner, restore, poolId, trader1 } = bootstrapMarkets({ + const { systems, signers, owner, restore, trader1 } = bootstrapMarkets({ synthMarkets: [], perpsMarkets: [], // don't create a market in bootstrap traderAccountIds: [2, 3], }); - let marketOwner: ethers.Signer, - anotherOwner: ethers.Signer, - randomAccount: ethers.Signer, - marketId: ethers.BigNumber; + let randomAccount: ethers.Signer; before('identify actors', async () => { - [, , marketOwner, anotherOwner, randomAccount] = signers(); + [, , , , randomAccount] = signers(); }); describe('market initialization', async () => { before(restore); - let marketId: ethers.BigNumber; + const marketId = BigNumber.from(25); let tx: ethers.providers.TransactionResponse; - describe('with zero address for market owner', () => { - it('reverts', async () => { - await assertRevert( - systems().PerpsMarket.createMarket(name, token, ethers.constants.AddressZero), - 'InvalidMarketOwner' - ); - }); - }); - describe('when the market is created', () => { before('create perps market', async () => { - marketId = await systems().PerpsMarket.callStatic.createMarket( - name, - token, - marketOwner.getAddress() - ); - tx = await systems().PerpsMarket.createMarket(name, token, marketOwner.getAddress()); + tx = await systems().PerpsMarket.createMarket(marketId, name, token); }); it('emits event', async () => { await assertEvent( tx, - `MarketRegistered(${marketId}, "${await marketOwner.getAddress()}", "${name}", "${token}")`, + `MarketCreated(${marketId}, "${name}", "${token}")`, systems().PerpsMarket ); }); - it('should be able to get market name', async () => { - assert.equal(await systems().PerpsMarket.name(marketId), name + ' Perps Market'); - }); - - it('should be able to get market symbol', async () => { - assert.equal(await systems().PerpsMarket.symbol(marketId), token); - }); - - it('should be able to get market owner', async () => { - assert.equal( - await systems().PerpsMarket.getMarketOwner(marketId), - await marketOwner.getAddress() - ); + it('should return proper metadata', async () => { + const metadata = await systems().PerpsMarket.metadata(marketId); + assert.equal(metadata.name, name); + assert.equal(metadata.symbol, token); }); }); describe('after market is created', () => { before('set max market value', async () => { - tx = await systems() - .PerpsMarket.connect(marketOwner) - .setMaxMarketSize(marketId, bn(99999999)); + tx = await systems().PerpsMarket.connect(owner()).setMaxMarketSize(marketId, bn(99999999)); }); it('should emit MaxMarketSizeSet event', async () => { @@ -92,110 +64,107 @@ describe('Create Market test', () => { }); }); - describe('change ownership', async () => { - before(restore); - - let tx: ethers.providers.TransactionResponse; - - before('create perps market', async () => { - marketId = await systems().PerpsMarket.callStatic.createMarket( - name, - token, - marketOwner.getAddress() - ); - await systems().PerpsMarket.createMarket(name, token, marketOwner.getAddress()); - }); - - describe('some account other than owner', () => { - it('reverts attempt to change ownership', async () => { - await assertRevert( - systems() - .PerpsMarket.connect(randomAccount) - .nominateMarketOwner(marketId, anotherOwner.getAddress()), - 'Unauthorized' - ); - }); - - it('reverts attempt to accept ownership', async () => { - await assertRevert( - systems().PerpsMarket.connect(randomAccount).acceptMarketOwnership(marketId), - 'NotNominated' - ); - }); - }); - - describe('owner nominates address zero', () => { - it('reverts', async () => { - await assertRevert( - systems() - .PerpsMarket.connect(marketOwner) - .nominateMarketOwner(marketId, ethers.constants.AddressZero), - 'ZeroAddress' - ); - }); - }); - - describe('owner nominates', () => { - before('nominate', async () => { - tx = await systems() - .PerpsMarket.connect(marketOwner) - .nominateMarketOwner(marketId, anotherOwner.getAddress()); - }); - - it('emits event', async () => { - await assertEvent( - tx, - `MarketOwnerNominated(${marketId}, "${await anotherOwner.getAddress()}")`, - systems().PerpsMarket - ); - }); - - it('reverts if accepted by other address', async () => { - await assertRevert( - systems().PerpsMarket.connect(randomAccount).acceptMarketOwnership(marketId), - 'NotNominated' - ); - }); - - describe('nominated address accepts', () => { - before('accept', async () => { - tx = await systems().PerpsMarket.connect(anotherOwner).acceptMarketOwnership(marketId); - }); - - it('emits event', async () => { - await assertEvent( - tx, - `MarketOwnerChanged(${marketId}, "${await marketOwner.getAddress()}", "${await anotherOwner.getAddress()}")`, - systems().PerpsMarket - ); - }); - - it('changed owner', async () => { - assert.equal( - await systems().PerpsMarket.getMarketOwner(marketId), - await anotherOwner.getAddress() - ); - }); - }); - }); - }); + // TODO: move to proxy level test + // describe('change ownership', async () => { + // before(restore); + + // let tx: ethers.providers.TransactionResponse; + + // before('create perps market', async () => { + // marketId = await systems().PerpsMarket.callStatic.createMarket( + // name, + // token, + // marketOwner.getAddress() + // ); + // await systems().PerpsMarket.createMarket(name, token, marketOwner.getAddress()); + // }); + + // describe('some account other than owner', () => { + // it('reverts attempt to change ownership', async () => { + // await assertRevert( + // systems() + // .PerpsMarket.connect(randomAccount) + // .nominateMarketOwner(marketId, anotherOwner.getAddress()), + // 'Unauthorized' + // ); + // }); + + // it('reverts attempt to accept ownership', async () => { + // await assertRevert( + // systems().PerpsMarket.connect(randomAccount).acceptMarketOwnership(marketId), + // 'NotNominated' + // ); + // }); + // }); + + // describe('owner nominates address zero', () => { + // it('reverts', async () => { + // await assertRevert( + // systems() + // .PerpsMarket.connect(marketOwner) + // .nominateMarketOwner(marketId, ethers.constants.AddressZero), + // 'ZeroAddress' + // ); + // }); + // }); + + // describe('owner nominates', () => { + // before('nominate', async () => { + // tx = await systems() + // .PerpsMarket.connect(marketOwner) + // .nominateMarketOwner(marketId, anotherOwner.getAddress()); + // }); + + // it('emits event', async () => { + // await assertEvent( + // tx, + // `MarketOwnerNominated(${marketId}, "${await anotherOwner.getAddress()}")`, + // systems().PerpsMarket + // ); + // }); + + // it('reverts if accepted by other address', async () => { + // await assertRevert( + // systems().PerpsMarket.connect(randomAccount).acceptMarketOwnership(marketId), + // 'NotNominated' + // ); + // }); + + // describe('nominated address accepts', () => { + // before('accept', async () => { + // tx = await systems().PerpsMarket.connect(anotherOwner).acceptMarketOwnership(marketId); + // }); + + // it('emits event', async () => { + // await assertEvent( + // tx, + // `MarketOwnerChanged(${marketId}, "${await marketOwner.getAddress()}", "${await anotherOwner.getAddress()}")`, + // systems().PerpsMarket + // ); + // }); + + // it('changed owner', async () => { + // assert.equal( + // await systems().PerpsMarket.getMarketOwner(marketId), + // await anotherOwner.getAddress() + // ); + // }); + // }); + // }); + // }); describe('market operation and configuration', async () => { before(restore); - let oracleNodeId: string, marketId: ethers.BigNumber; + const marketId = BigNumber.from(25); + let oracleNodeId: string; before('create perps market', async () => { - marketId = await systems().PerpsMarket.callStatic.createMarket( - name, - token, - marketOwner.getAddress() - ); - await systems().PerpsMarket.createMarket(name, token, marketOwner.getAddress()); + await systems().PerpsMarket.connect(owner()).createMarket(marketId, name, token); }); before('set max market value', async () => { - await systems().PerpsMarket.connect(marketOwner).setMaxMarketSize(marketId, bn(99999999)); + await systems().PerpsMarket.connect(owner()).setMaxMarketSize(marketId, bn(99999999)); }); before('create price nodes', async () => { @@ -216,7 +185,7 @@ describe('Create Market test', () => { it('reverts when trying to use the market', async () => { await assertRevert( systems() - .PerpsMarket.connect(marketOwner) + .PerpsMarket.connect(owner()) .commitOrder({ marketId: marketId, accountId: 2, @@ -232,25 +201,12 @@ describe('Create Market test', () => { describe('when price data is updated', () => { before('update price data', async () => { - await systems().PerpsMarket.connect(marketOwner).updatePriceData(marketId, oracleNodeId); - }); - - // Need to do some configuration to make sure the market is ready to use - before('delegate collateral from pool to market', async () => { - await systems() - .Core.connect(owner()) - .setPoolConfiguration(poolId, [ - { - marketId, - weightD18: ethers.utils.parseEther('1'), - maxDebtShareValueD18: ethers.utils.parseEther('1'), - }, - ]); + await systems().PerpsMarket.connect(owner()).updatePriceData(marketId, oracleNodeId); }); before('create settlement strategy', async () => { await systems() - .PerpsMarket.connect(marketOwner) + .PerpsMarket.connect(owner()) .addSettlementStrategy(marketId, { strategyType: 0, settlementDelay: 5, @@ -267,7 +223,7 @@ describe('Create Market test', () => { before('set skew scale', async () => { await systems() - .PerpsMarket.connect(marketOwner) + .PerpsMarket.connect(owner()) .setFundingParameters(marketId, bn(100_000), bn(0)); }); @@ -293,15 +249,10 @@ describe('Create Market test', () => { describe('market interface views', async () => { before(restore); - let marketId: ethers.BigNumber; + const marketId = BigNumber.from(25); before('create perps market', async () => { - marketId = await systems().PerpsMarket.callStatic.createMarket( - name, - token, - marketOwner.getAddress() - ); - await systems().PerpsMarket.createMarket(name, token, marketOwner.getAddress()); + await systems().PerpsMarket.createMarket(marketId, name, token); }); before('create price nodes', async () => { diff --git a/markets/perps-market/test/integration/Market/MarketConfiguration.test.ts b/markets/perps-market/test/integration/Market/MarketConfiguration.test.ts index e1c0dad491..1e9205492f 100644 --- a/markets/perps-market/test/integration/Market/MarketConfiguration.test.ts +++ b/markets/perps-market/test/integration/Market/MarketConfiguration.test.ts @@ -1,12 +1,13 @@ import { bn } from '@synthetixio/main/test/common'; import { bootstrapMarkets } from '../bootstrap'; -import { BigNumber, Signer, utils } from 'ethers'; +import { Signer, utils } from 'ethers'; import assertRevert from '@synthetixio/core-utils/src/utils/assertions/assert-revert'; import assertBn from '@synthetixio/core-utils/src/utils/assertions/assert-bignumber'; import assertEvent from '@synthetixio/core-utils/src/utils/assertions/assert-event'; import assert from 'assert'; describe('MarketConfiguration', async () => { + const marketId = 25; const fixture = { token: 'snxETH', marketName: 'TestPerpsMarket', @@ -36,39 +37,26 @@ describe('MarketConfiguration', async () => { maxSecondsInLiquidationWindow: bn(10), }; - const { systems, signers } = bootstrapMarkets({ + const { systems, signers, owner } = bootstrapMarkets({ synthMarkets: [], perpsMarkets: [], traderAccountIds: [], }); - - let marketId: BigNumber; let randomUser: Signer; - let marketOwner: Signer; before('identify actors', async () => { - const [, owner, randomAccount] = signers(); + const [, , randomAccount] = signers(); randomUser = randomAccount; - marketOwner = owner; }); before('create perps market', async () => { - marketId = await systems().PerpsMarket.callStatic.createMarket( - fixture.marketName, - fixture.token, - marketOwner.getAddress() - ); - await systems().PerpsMarket.createMarket( - fixture.marketName, - fixture.token, - await marketOwner.getAddress() - ); + await systems().PerpsMarket.createMarket(marketId, fixture.marketName, fixture.token); }); it('owner can set settlement strategy and events are emitted', async () => { await assertEvent( await systems() - .PerpsMarket.connect(marketOwner) + .PerpsMarket.connect(owner()) .addSettlementStrategy(marketId, fixture.settlementStrategy), 'SettlementStrategyAdded(' + marketId.toString() + @@ -99,7 +87,7 @@ describe('MarketConfiguration', async () => { it('owner can enable settlement strategy and events are emitted', async () => { await assertEvent( await systems() - .PerpsMarket.connect(marketOwner) + .PerpsMarket.connect(owner()) .setSettlementStrategyEnabled(marketId, 0, fixture.settlementStrategy.disabled), 'SettlementStrategyEnabled(' + marketId.toString() + @@ -115,7 +103,7 @@ describe('MarketConfiguration', async () => { it('owner can set order fees and events are emitted', async () => { await assertEvent( await systems() - .PerpsMarket.connect(marketOwner) + .PerpsMarket.connect(owner()) .setOrderFees(marketId, fixture.orderFees.makerFee, fixture.orderFees.takerFee), 'OrderFeesSet(' + marketId.toString() + @@ -130,7 +118,7 @@ describe('MarketConfiguration', async () => { it('owner can set max market value and events are emitted', async () => { await assertEvent( await systems() - .PerpsMarket.connect(marketOwner) + .PerpsMarket.connect(owner()) .setMaxMarketSize(marketId, fixture.maxMarketValue), 'MaxMarketSizeSet(' + marketId.toString() + ', ' + fixture.maxMarketValue.toString() + ')', systems().PerpsMarket @@ -140,7 +128,7 @@ describe('MarketConfiguration', async () => { it('owner can set funding parameters and events are emitted', async () => { await assertEvent( await systems() - .PerpsMarket.connect(marketOwner) + .PerpsMarket.connect(owner()) .setFundingParameters(marketId, fixture.skewScale, fixture.maxFundingVelocity), 'FundingParametersSet(' + marketId.toString() + @@ -156,7 +144,7 @@ describe('MarketConfiguration', async () => { it('owner can set liquidation parameters and events are emitted', async () => { await assertEvent( await systems() - .PerpsMarket.connect(marketOwner) + .PerpsMarket.connect(owner()) .setLiquidationParameters( marketId, fixture.initialMarginFraction, @@ -175,7 +163,7 @@ describe('MarketConfiguration', async () => { it('owner can set all locked OI percentage and events are emitted', async () => { await assertEvent( await systems() - .PerpsMarket.connect(marketOwner) + .PerpsMarket.connect(owner()) .setLockedOiRatio(marketId, fixture.lockedOiPercentRatioD18), 'LockedOiRatioD18Set(' + marketId.toString() + @@ -187,34 +175,31 @@ describe('MarketConfiguration', async () => { }); it('should revert transaction when not market owner sets parameters', async () => { - const owner = await marketOwner.getAddress(); - const randomUserAddress = await randomUser.getAddress(); - await assertRevert( systems() .PerpsMarket.connect(randomUser) .addSettlementStrategy(marketId, fixture.settlementStrategy), - `OnlyMarketOwner("${owner}", "${randomUserAddress}")` + 'Unauthorized' ); await assertRevert( systems().PerpsMarket.connect(randomUser).setSettlementStrategyEnabled(marketId, 0, true), - `OnlyMarketOwner("${owner}", "${randomUserAddress}")` + 'Unauthorized' ); await assertRevert( systems() .PerpsMarket.connect(randomUser) .setOrderFees(marketId, fixture.orderFees.makerFee, fixture.orderFees.takerFee), - `OnlyMarketOwner("${owner}", "${randomUserAddress}")` + 'Unauthorized' ); await assertRevert( systems().PerpsMarket.connect(randomUser).setMaxMarketSize(marketId, fixture.maxMarketValue), - `OnlyMarketOwner("${owner}", "${randomUserAddress}")` + 'Unauthorized' ); await assertRevert( systems() .PerpsMarket.connect(randomUser) .setFundingParameters(marketId, fixture.skewScale, fixture.maxFundingVelocity), - `OnlyMarketOwner("${owner}", "${randomUserAddress}")` + 'Unauthorized' ); await assertRevert( systems() @@ -228,13 +213,13 @@ describe('MarketConfiguration', async () => { fixture.maxSecondsInLiquidationWindow, fixture.minimumPositionMargin ), - `OnlyMarketOwner("${owner}", "${randomUserAddress}")` + 'Unauthorized' ); await assertRevert( systems() .PerpsMarket.connect(randomUser) .setLockedOiRatio(marketId, fixture.lockedOiPercentRatioD18), - `OnlyMarketOwner("${owner}", "${randomUserAddress}")` + 'Unauthorized' ); }); diff --git a/markets/perps-market/test/integration/Market/PerpsMarketModule.test.ts b/markets/perps-market/test/integration/Market/PerpsMarketModule.test.ts index 83e8a94c24..92f3854074 100644 --- a/markets/perps-market/test/integration/Market/PerpsMarketModule.test.ts +++ b/markets/perps-market/test/integration/Market/PerpsMarketModule.test.ts @@ -14,7 +14,7 @@ describe('PerpsMarketModule', () => { marketTokenPrice: bn(1000), }; - const { systems, perpsMarkets, marketOwner, provider, trader2, keeper } = bootstrapMarkets({ + const { systems, perpsMarkets, owner, provider, trader2, keeper } = bootstrapMarkets({ synthMarkets: [ { name: 'Ether', @@ -25,6 +25,7 @@ describe('PerpsMarketModule', () => { ], perpsMarkets: [ { + requestedMarketId: 50, name: 'Ether', token: 'snxETH', price: fixture.marketTokenPrice, @@ -85,7 +86,7 @@ describe('PerpsMarketModule', () => { describe('skewScale 0', () => { const restoreSkewScale = snapshotCheckpoint(provider); before('set skewScale to 0', async () => { - await systems().PerpsMarket.connect(marketOwner()).setFundingParameters(marketId, 0, 0); + await systems().PerpsMarket.connect(owner()).setFundingParameters(marketId, 0, 0); }); it('should return the index price', async () => { const price = await systems().PerpsMarket.fillPrice(marketId, bn(1), bn(1000)); diff --git a/markets/perps-market/test/integration/Market/Size.test.ts b/markets/perps-market/test/integration/Market/Size.test.ts index 999a9d299b..aa23fb69d2 100644 --- a/markets/perps-market/test/integration/Market/Size.test.ts +++ b/markets/perps-market/test/integration/Market/Size.test.ts @@ -8,6 +8,7 @@ describe('Market - size test', () => { synthMarkets: [], perpsMarkets: [ { + requestedMarketId: 25, name: 'Ether', token: 'snxETH', price: bn(2000), diff --git a/markets/perps-market/test/integration/Markets/GlobalPerpsMarket.test.ts b/markets/perps-market/test/integration/Markets/GlobalPerpsMarket.test.ts index 81a7589b41..90a112e7dc 100644 --- a/markets/perps-market/test/integration/Markets/GlobalPerpsMarket.test.ts +++ b/markets/perps-market/test/integration/Markets/GlobalPerpsMarket.test.ts @@ -6,7 +6,7 @@ import assertRevert from '@synthetixio/core-utils/utils/assertions/assert-revert describe('GlobalPerpsMarket', () => { const { systems, perpsMarkets, trader1 } = bootstrapMarkets({ synthMarkets: [{ name: 'Ether', token: 'snxETH', buyPrice: bn(1000), sellPrice: bn(1000) }], - perpsMarkets: [{ name: 'Ether', token: 'snxETH', price: bn(1000) }], + perpsMarkets: [{ requestedMarketId: 25, name: 'Ether', token: 'snxETH', price: bn(1000) }], traderAccountIds: [], }); diff --git a/markets/perps-market/test/integration/Orders/OffchainAsyncOrder.cancel.test.ts b/markets/perps-market/test/integration/Orders/OffchainAsyncOrder.cancel.test.ts index 17580d3867..6baff6a311 100644 --- a/markets/perps-market/test/integration/Orders/OffchainAsyncOrder.cancel.test.ts +++ b/markets/perps-market/test/integration/Orders/OffchainAsyncOrder.cancel.test.ts @@ -11,6 +11,7 @@ describe('Cancel Offchain Async Order test', () => { synthMarkets: [], perpsMarkets: [ { + requestedMarketId: 25, name: 'Ether', token: 'snxETH', price: bn(1000), @@ -77,7 +78,11 @@ describe('Cancel Offchain Async Order test', () => { }); it('emits event when order is canceled', async () => { // Ignore settlement time and price for the event - await assertEvent(tx, `OrderCanceled(1, 2,`, systems().PerpsMarket); + await assertEvent( + tx, + `OrderCanceled(${perpsMarkets()[0].marketId()}, 2,`, + systems().PerpsMarket + ); }); it('sizeDelta is 0 when order is canceled', async () => { const orderAfterCancelation = await systems().PerpsMarket.getOrder(ethMarketId, 2); diff --git a/markets/perps-market/test/integration/Orders/OffchainAsyncOrder.commit.test.ts b/markets/perps-market/test/integration/Orders/OffchainAsyncOrder.commit.test.ts index 0228219f71..821a0d50c3 100644 --- a/markets/perps-market/test/integration/Orders/OffchainAsyncOrder.commit.test.ts +++ b/markets/perps-market/test/integration/Orders/OffchainAsyncOrder.commit.test.ts @@ -22,6 +22,7 @@ describe('Commit Offchain Async Order test', () => { ], perpsMarkets: [ { + requestedMarketId: 25, name: 'Ether', token: 'snxETH', price: bn(1000), diff --git a/markets/perps-market/test/integration/Orders/OffchainAsyncOrder.fees.test.ts b/markets/perps-market/test/integration/Orders/OffchainAsyncOrder.fees.test.ts index 2a5e41b403..f23ed11bb3 100644 --- a/markets/perps-market/test/integration/Orders/OffchainAsyncOrder.fees.test.ts +++ b/markets/perps-market/test/integration/Orders/OffchainAsyncOrder.fees.test.ts @@ -25,6 +25,7 @@ describe('Offchain Async Order test - fees', () => { ], perpsMarkets: [ { + requestedMarketId: 25, name: 'Ether', token: 'snxETH', price: ethPrice, @@ -96,7 +97,6 @@ describe('Offchain Async Order test - fees', () => { describe(`Using ${testCase.name} as collateral`, () => { let balancesBeforeLong: { traderBalance: ethers.BigNumber; - perpMarketWithdrawable: ethers.BigNumber; keeperBalance: ethers.BigNumber; }; @@ -141,10 +141,9 @@ describe('Offchain Async Order test - fees', () => { }); it('validate that not fees are paid on commit', async () => { - const { traderBalance, perpMarketWithdrawable, keeperBalance } = await getBalances(); + const { traderBalance, keeperBalance } = await getBalances(); assertBn.equal(traderBalance, balancesBeforeLong.traderBalance); - assertBn.equal(perpMarketWithdrawable, balancesBeforeLong.perpMarketWithdrawable); assertBn.equal(keeperBalance, balancesBeforeLong.keeperBalance); }); @@ -165,10 +164,9 @@ describe('Offchain Async Order test - fees', () => { }); it('validate no fees are paid on cancel', async () => { - const { traderBalance, perpMarketWithdrawable, keeperBalance } = await getBalances(); + const { traderBalance, keeperBalance } = await getBalances(); assertBn.equal(traderBalance, balancesBeforeLong.traderBalance); - assertBn.equal(perpMarketWithdrawable, balancesBeforeLong.perpMarketWithdrawable); assertBn.equal(keeperBalance, balancesBeforeLong.keeperBalance); }); }); @@ -191,16 +189,13 @@ describe('Offchain Async Order test - fees', () => { }); it('validate fees paid on settle', async () => { - const { traderBalance, perpMarketWithdrawable, keeperBalance } = await getBalances(); + const { traderBalance, keeperBalance } = await getBalances(); assertBn.equal( traderBalance, balancesBeforeLong.traderBalance.sub(feesPaidOnSettle.totalFees) ); - assertBn.equal( - perpMarketWithdrawable, - balancesBeforeLong.perpMarketWithdrawable.add(feesPaidOnSettle.perpsMarketFee) - ); + assertBn.equal( keeperBalance, balancesBeforeLong.keeperBalance.add(feesPaidOnSettle.keeperFee) @@ -214,7 +209,6 @@ describe('Offchain Async Order test - fees', () => { let balancesAfterLong: { traderBalance: ethers.BigNumber; - perpMarketWithdrawable: ethers.BigNumber; keeperBalance: ethers.BigNumber; accountPnl: ethers.BigNumber; }; @@ -269,10 +263,6 @@ describe('Offchain Async Order test - fees', () => { balancesAfterLong.traderBalance, balancesBeforeLong.traderBalance.sub(feesPaidOnLong.totalFees) ); - assertBn.equal( - balancesAfterLong.perpMarketWithdrawable, - balancesBeforeLong.perpMarketWithdrawable.add(feesPaidOnLong.perpsMarketFee) - ); assertBn.equal( balancesAfterLong.keeperBalance, balancesBeforeLong.keeperBalance.add(feesPaidOnLong.keeperFee) @@ -302,7 +292,7 @@ describe('Offchain Async Order test - fees', () => { }); it('validate fees paid on short position', async () => { - const { traderBalance, perpMarketWithdrawable, keeperBalance } = await getBalances(); + const { traderBalance, keeperBalance } = await getBalances(); assertBn.equal( traderBalance, @@ -310,12 +300,6 @@ describe('Offchain Async Order test - fees', () => { .sub(feesPaidOnShort.totalFees) .add(balancesAfterLong.accountPnl) ); - assertBn.equal( - perpMarketWithdrawable, - balancesAfterLong.perpMarketWithdrawable - .add(feesPaidOnShort.perpsMarketFee) - .sub(balancesAfterLong.accountPnl) - ); assertBn.equal( keeperBalance, balancesAfterLong.keeperBalance.add(feesPaidOnShort.keeperFee) @@ -344,16 +328,12 @@ describe('Offchain Async Order test - fees', () => { }); it('validate fees paid', async () => { - const { traderBalance, perpMarketWithdrawable, keeperBalance } = await getBalances(); + const { traderBalance, keeperBalance } = await getBalances(); assertBn.equal( traderBalance, balancesAfterLong.traderBalance.sub(feesPaidOnShort.totalFees) ); - assertBn.equal( - perpMarketWithdrawable, - balancesAfterLong.perpMarketWithdrawable.add(feesPaidOnShort.perpsMarketFee) - ); assertBn.equal( keeperBalance, balancesAfterLong.keeperBalance.add(feesPaidOnShort.keeperFee) @@ -366,12 +346,10 @@ describe('Offchain Async Order test - fees', () => { const getBalances = async () => { const traderBalance = await systems().PerpsMarket.totalCollateralValue(2); - const perpMarketWithdrawable = await systems().Core.getWithdrawableMarketUsd(ethMarketId); const keeperBalance = await systems().USD.balanceOf(keeper().getAddress()); const accountPnl = (await systems().PerpsMarket.getOpenPosition(2, ethMarketId))[0]; return { traderBalance, - perpMarketWithdrawable, keeperBalance, accountPnl, }; diff --git a/markets/perps-market/test/integration/Orders/OffchainAsyncOrder.pending.test.ts b/markets/perps-market/test/integration/Orders/OffchainAsyncOrder.pending.test.ts index 1421f549c7..b8ba36256e 100644 --- a/markets/perps-market/test/integration/Orders/OffchainAsyncOrder.pending.test.ts +++ b/markets/perps-market/test/integration/Orders/OffchainAsyncOrder.pending.test.ts @@ -12,12 +12,14 @@ describe('Offchain Async Order - Prevent updates with pending order test', () => synthMarkets: [], perpsMarkets: [ { + requestedMarketId: 25, name: 'Ether', token: 'snxETH', price: bn(1000), fundingParams: { skewScale: bn(100_000), maxFundingVelocity: bn(10) }, }, { + requestedMarketId: 30, name: 'Bitcoin', token: 'snxBTC', price: bn(10_000), diff --git a/markets/perps-market/test/integration/Orders/OffchainAsyncOrder.price.test.ts b/markets/perps-market/test/integration/Orders/OffchainAsyncOrder.price.test.ts index c6e563250c..4f0bae8ab2 100644 --- a/markets/perps-market/test/integration/Orders/OffchainAsyncOrder.price.test.ts +++ b/markets/perps-market/test/integration/Orders/OffchainAsyncOrder.price.test.ts @@ -12,6 +12,7 @@ describe('Offchain Async Order - Price tests', () => { synthMarkets: [], perpsMarkets: [ { + requestedMarketId: 25, name: 'Ether', token: 'snxETH', price: bn(1000), diff --git a/markets/perps-market/test/integration/Orders/OffchainAsyncOrder.settle.test.ts b/markets/perps-market/test/integration/Orders/OffchainAsyncOrder.settle.test.ts index 9c4f110f1a..c8ca65aad0 100644 --- a/markets/perps-market/test/integration/Orders/OffchainAsyncOrder.settle.test.ts +++ b/markets/perps-market/test/integration/Orders/OffchainAsyncOrder.settle.test.ts @@ -24,6 +24,7 @@ describe('Settle Offchain Async Order test', () => { ], perpsMarkets: [ { + requestedMarketId: 25, name: 'Ether', token: 'snxETH', price: bn(1000), @@ -395,6 +396,7 @@ describe('Settle Offchain Async Order test', () => { ethMarketId, accountId, fillPrice, + 0, sizeDelta, newPositionSize, totalFees, diff --git a/markets/perps-market/test/integration/Position/Funding.test.ts b/markets/perps-market/test/integration/Position/Funding.test.ts index e8734aba7f..f01d06069c 100644 --- a/markets/perps-market/test/integration/Position/Funding.test.ts +++ b/markets/perps-market/test/integration/Position/Funding.test.ts @@ -16,6 +16,7 @@ describe('Position - funding', () => { synthMarkets: [], perpsMarkets: [ { + requestedMarketId: 25, name: 'Ether', token: 'snxETH', price: _ETH_PRICE, diff --git a/markets/perps-market/test/integration/bootstrap/bootstrap.ts b/markets/perps-market/test/integration/bootstrap/bootstrap.ts index 724f24e1a6..12923365e0 100644 --- a/markets/perps-market/test/integration/bootstrap/bootstrap.ts +++ b/markets/perps-market/test/integration/bootstrap/bootstrap.ts @@ -89,7 +89,7 @@ export function bootstrapMarkets(data: BootstrapArgs) { const { synthMarkets } = bootstrapSynthMarkets(data.synthMarkets, chainStateWithPerpsMarkets); - const { systems, signers, provider, owner, perpsMarkets, marketOwner, poolId } = + const { systems, signers, provider, owner, perpsMarkets, marketOwner, poolId, superMarketId } = chainStateWithPerpsMarkets; const { trader1, trader2, keeper, restore } = bootstrapTraders({ systems, @@ -108,6 +108,18 @@ export function bootstrapMarkets(data: BootstrapArgs) { } }); + before('set max market collateral allowed for all synths', async () => { + for (const { synthAddress } of synthMarkets()) { + await systems() + .Core.connect(owner()) + .configureMaximumMarketCollateral( + chainStateWithPerpsMarkets.superMarketId(), + synthAddress(), + ethers.constants.MaxUint256 + ); + } + }); + // auto add all synth markets in the row they were created for deduction priority before('set synth deduction priority', async () => { // first item is always snxUSD @@ -138,6 +150,7 @@ export function bootstrapMarkets(data: BootstrapArgs) { perpsMarkets, synthMarkets, marketOwner, + superMarketId, poolId, }; } diff --git a/markets/perps-market/test/integration/bootstrap/bootstrapPerpsMarkets.ts b/markets/perps-market/test/integration/bootstrap/bootstrapPerpsMarkets.ts index 618011f222..48c79263ff 100644 --- a/markets/perps-market/test/integration/bootstrap/bootstrapPerpsMarkets.ts +++ b/markets/perps-market/test/integration/bootstrap/bootstrapPerpsMarkets.ts @@ -15,6 +15,7 @@ export type PerpsMarket = { export type PerpsMarkets = Array; export type PerpsMarketData = Array<{ + requestedMarketId: ethers.BigNumber; name: string; token: string; price: ethers.BigNumber; @@ -70,18 +71,28 @@ export const bootstrapPerpsMarkets = ( chainState: IncomingChainState | undefined ) => { const r: IncomingChainState = chainState ?? createStakedPool(bootstrap(), bn(2000)); - let contracts: Systems, marketOwner: ethers.Signer; + let contracts: Systems, superMarketId: ethers.BigNumber; before('identify contracts', () => { contracts = r.systems() as Systems; }); - before('identify market owner', async () => { - [, , marketOwner] = r.signers(); + before('create super market', async () => { + superMarketId = await contracts.PerpsMarket.callStatic.initializeFactory(); + await contracts.PerpsMarket.initializeFactory(); + + await contracts.Core.connect(r.owner()).setPoolConfiguration(r.poolId, [ + { + marketId: superMarketId, + weightD18: ethers.utils.parseEther('1'), + maxDebtShareValueD18: ethers.utils.parseEther('1'), + }, + ]); }); const perpsMarkets: PerpsMarkets = data.map( ({ + requestedMarketId: marketId, name, token, price, @@ -92,7 +103,7 @@ export const bootstrapPerpsMarkets = ( lockedOiRatioD18, settlementStrategy, }) => { - let oracleNodeId: string, aggregator: AggregatorV3Mock, marketId: ethers.BigNumber; + let oracleNodeId: string, aggregator: AggregatorV3Mock; before('create price nodes', async () => { const results = await createOracleNode(r.owner(), price, r.systems().OracleManager); oracleNodeId = results.oracleNodeId; @@ -100,27 +111,12 @@ export const bootstrapPerpsMarkets = ( }); before(`create perps market ${name}`, async () => { - marketId = await contracts.PerpsMarket.callStatic.createMarket( - name, - token, - marketOwner.getAddress() - ); - await contracts.PerpsMarket.createMarket(name, token, marketOwner.getAddress()); - await contracts.PerpsMarket.connect(marketOwner).updatePriceData(marketId, oracleNodeId); - }); - - before('delegate collateral from pool to market', async () => { - await contracts.Core.connect(r.owner()).setPoolConfiguration(r.poolId, [ - { - marketId, - weightD18: ethers.utils.parseEther('1'), - maxDebtShareValueD18: ethers.utils.parseEther('1'), - }, - ]); + await contracts.PerpsMarket.createMarket(marketId, name, token); + await contracts.PerpsMarket.connect(r.owner()).updatePriceData(marketId, oracleNodeId); }); before('set funding parameters', async () => { - await contracts.PerpsMarket.connect(marketOwner).setFundingParameters( + await contracts.PerpsMarket.connect(r.owner()).setFundingParameters( marketId, fundingParams ? fundingParams.skewScale : bn(1_000_000), fundingParams ? fundingParams.maxFundingVelocity : 0 @@ -128,7 +124,7 @@ export const bootstrapPerpsMarkets = ( }); before('set max market value', async () => { - await contracts.PerpsMarket.connect(marketOwner).setMaxMarketSize( + await contracts.PerpsMarket.connect(r.owner()).setMaxMarketSize( marketId, maxMarketValue ? maxMarketValue : bn(10_000_000) ); @@ -136,7 +132,7 @@ export const bootstrapPerpsMarkets = ( if (orderFees) { before('set fees', async () => { - await contracts.PerpsMarket.connect(marketOwner).setOrderFees( + await contracts.PerpsMarket.connect(r.owner()).setOrderFees( marketId, orderFees.makerFee, orderFees.takerFee @@ -146,7 +142,7 @@ export const bootstrapPerpsMarkets = ( if (liquidationParams) { before('set liquidation parameters', async () => { - await contracts.PerpsMarket.connect(marketOwner).setLiquidationParameters( + await contracts.PerpsMarket.connect(r.owner()).setLiquidationParameters( marketId, liquidationParams.initialMarginFraction, liquidationParams.maintenanceMarginFraction, @@ -160,7 +156,7 @@ export const bootstrapPerpsMarkets = ( if (lockedOiRatioD18) { before('set locked oi percent', async () => { - await contracts.PerpsMarket.connect(marketOwner).setLockedOiRatio( + await contracts.PerpsMarket.connect(r.owner()).setLockedOiRatio( marketId, lockedOiRatioD18 ); @@ -177,10 +173,10 @@ export const bootstrapPerpsMarkets = ( }; // first call is static to get strategyId strategyId = await contracts.PerpsMarket.connect( - marketOwner + r.owner() ).callStatic.addSettlementStrategy(marketId, strategy); - await contracts.PerpsMarket.connect(marketOwner).addSettlementStrategy(marketId, strategy); + await contracts.PerpsMarket.connect(r.owner()).addSettlementStrategy(marketId, strategy); }); return { @@ -196,8 +192,8 @@ export const bootstrapPerpsMarkets = ( return { ...r, restore, + superMarketId: () => superMarketId, systems: () => contracts, - marketOwner: () => marketOwner, perpsMarkets: () => perpsMarkets, poolId: r.poolId, }; diff --git a/markets/spot-market/test/common/bootstrapSynthMarkets.ts b/markets/spot-market/test/common/bootstrapSynthMarkets.ts index 1b4eae982b..938204607a 100644 --- a/markets/spot-market/test/common/bootstrapSynthMarkets.ts +++ b/markets/spot-market/test/common/bootstrapSynthMarkets.ts @@ -11,6 +11,7 @@ export type SynthMarkets = Array<{ buyAggregator: () => AggregatorV3Mock; sellAggregator: () => AggregatorV3Mock; synth: () => SynthRouter; + synthAddress: () => string; }>; export type SynthArguments = Array<{ @@ -36,6 +37,7 @@ export function bootstrapSynthMarkets( buyAggregator: AggregatorV3Mock, sellNodeId: string, sellAggregator: AggregatorV3Mock, + synthAddress: string, synth: SynthRouter; before('create price nodes', async () => { @@ -67,7 +69,8 @@ export function bootstrapSynthMarkets( buyNodeId, sellNodeId ); - synth = contracts.Synth(await contracts.SpotMarket.getSynth(marketId)); + synthAddress = await contracts.SpotMarket.getSynth(marketId); + synth = contracts.Synth(synthAddress); }); before('delegate collateral to market from pool', async () => { @@ -80,11 +83,25 @@ export function bootstrapSynthMarkets( ]); }); + before('allow synth as collateral in system', async () => { + const tokenAddress = await contracts.SpotMarket.getSynth(marketId); + await r.systems().Core.connect(r.owner()).configureCollateral({ + tokenAddress, + oracleNodeId: buyNodeId, + issuanceRatioD18: '5000000000000000000', + liquidationRatioD18: '1500000000000000000', + liquidationRewardD18: '20000000000000000000', + minDelegationD18: '20000000000000000000', + depositingEnabled: false, + }); + }); + return { marketId: () => marketId, buyAggregator: () => buyAggregator, sellAggregator: () => sellAggregator, synth: () => synth, + synthAddress: () => synthAddress, }; }); From cffaa5e10546269332a9ecc7845b0f9589a01df4 Mon Sep 17 00:00:00 2001 From: Leonardo Massazza Date: Mon, 24 Jul 2023 11:42:30 +0100 Subject: [PATCH 10/63] Natspec to AsyncOrder and others (#1716) --- .../contracts/storage/AsyncOrder.sol | 132 +++++++++++++++--- .../contracts/storage/GlobalPerpsMarket.sol | 37 +++-- .../GlobalPerpsMarketConfiguration.sol | 6 +- .../contracts/storage/OrderFee.sol | 9 ++ 4 files changed, 157 insertions(+), 27 deletions(-) diff --git a/markets/perps-market/contracts/storage/AsyncOrder.sol b/markets/perps-market/contracts/storage/AsyncOrder.sol index e570925650..30b8188ce0 100644 --- a/markets/perps-market/contracts/storage/AsyncOrder.sol +++ b/markets/perps-market/contracts/storage/AsyncOrder.sol @@ -12,6 +12,9 @@ import {PerpsAccount} from "./PerpsAccount.sol"; import {MathUtil} from "../utils/MathUtil.sol"; import {OrderFee} from "./OrderFee.sol"; +/** + * @title Async order top level data storage + */ library AsyncOrder { using DecimalMath for int256; using DecimalMath for int128; @@ -25,22 +28,35 @@ library AsyncOrder { using PerpsAccount for PerpsAccount.Data; using Position for Position.Data; + /** + * @notice Thrown when attempting to settle an expired order. + */ error SettlementWindowExpired( uint256 timestamp, uint256 settlementTime, uint256 settlementExpiration ); + /** + * @notice Thrown when attempting to cancel an order that is not yet expired. + */ error SettlementWindowNotExpired( uint256 timestamp, uint256 settlementTime, uint256 settlementExpiration ); - error AcceptablePriceExceeded(uint256 acceptablePrice, uint256 fillPrice); - + /** + * @notice Thrown when order does not exist. + * @dev Order does not exist if the order sizeDelta is 0. + */ error OrderNotValid(); + /** + * @notice Thrown when fill price exceeds the acceptable price set at submission. + */ + error AcceptablePriceExceeded(uint256 acceptablePrice, uint256 fillPrice); + /** * @notice Gets thrown when commit order is called when a pending order already exists. */ @@ -51,25 +67,78 @@ library AsyncOrder { */ error PendingOrderExist(); + /** + * @notice Thrown when commiting an order with sizeDelta is zero. + * @dev Size delta 0 is used to flag a non-valid order since it's a non-update order. + */ + error ZeroSizeOrder(); + + /** + * @notice Thrown when there's not enough margin to cover the order and settlement costs associated. + */ + error InsufficientMargin(int availableMargin, uint minMargin); + struct Data { + /** + * @dev Order account id. + */ uint128 accountId; + /** + * @dev Order market id. + */ uint128 marketId; + /** + * @dev Order size delta (of asset units expressed in decimal 18 digits). It can be positive or negative. + */ int128 sizeDelta; + /** + * @dev Settlement strategy used for the order. + */ uint128 settlementStrategyId; + /** + * @dev Time at which the Settlement time is open. + */ uint256 settlementTime; + /** + * @dev Acceptable price set at submission. Longs will not be filled above this price, and shorts will not be filled below it. + */ uint256 acceptablePrice; + /** + * @dev An optional code provided by frontends to assist with tracking the source of volume and fees. + */ bytes32 trackingCode; } struct OrderCommitmentRequest { + /** + * @dev Order market id. + */ uint128 marketId; + /** + * @dev Order account id. + */ uint128 accountId; + /** + * @dev Order size delta (of asset units expressed in decimal 18 digits). It can be positive or negative. + */ int128 sizeDelta; + /** + * @dev Settlement strategy used for the order. + */ uint128 settlementStrategyId; + /** + * @dev Acceptable price set at submission. + */ uint256 acceptablePrice; + /** + * @dev An optional code provided by frontends to assist with tracking the source of volume and fees. + */ bytes32 trackingCode; } + /** + * @notice Updates the order with the commitment request data and settlement time. + */ function load(uint128 accountId) internal pure returns (Data storage order) { bytes32 s = keccak256(abi.encode("io.synthetix.perps-market.AsyncOrder", accountId)); @@ -124,12 +193,21 @@ library AsyncOrder { self.accountId = commitment.accountId; } + /** + * @notice Resets the order. + * @dev This function is called after the order is settled or cancelled. + * @dev Just setting the sizeDelta to 0 is enough, since is the value checked to identify an active order at settlement time. + * @dev The rest of the fields will be updated on the next commitment. Not doing it here is more gas efficient. + */ function reset(Data storage self) internal { self.sizeDelta = 0; - - // setting the rest to 0 is not necessary, and is gas inefficient since it will be overwritten at new order claim. } + /** + * @notice Checks if the order window settlement is opened and expired. + * @dev Reverts if block.timestamp is < settlementTime (not <=, so even if the settlementDelay is set to zero, it will require at least 1 second waiting time) + * @dev Reverts if block.timestamp is > settlementTime + settlementWindowDuration + */ function checkWithinSettlementWindow( Data storage self, SettlementStrategy.Data storage settlementStrategy @@ -145,6 +223,11 @@ library AsyncOrder { } } + /** + * @notice Checks if the order can be cancelled. + * @dev Reverts if block.timestamp is < settlementTime + settlementWindowDuration + * @dev it means it didn't expire yet. + */ function checkCancellationEligibility( Data storage self, SettlementStrategy.Data storage settlementStrategy @@ -160,9 +243,18 @@ library AsyncOrder { } } - error ZeroSizeOrder(); - error InsufficientMargin(int availableMargin, uint minMargin); + /** + * @notice Checks if the storage order is valid (exists), and reverts otherwise + */ + function checkValidity(Data storage self) internal view { + if (self.sizeDelta == 0) { + revert OrderNotValid(); + } + } + /** + * @dev Struct used internally in validateOrder() to prevent stack too deep error. + */ struct SimulateDataRuntime { uint fillPrice; uint orderFees; @@ -178,20 +270,22 @@ library AsyncOrder { bytes32 trackingCode; } + /** + * @notice Checks if the order can be settled. + * @dev it recomputes market funding rate, calculates fill price and fees for the order + * @dev and with that data it checks that: + * @dev - the account is eligible for liquidation + * @dev - the fill price is within the acceptable price range + * @dev - the position size doesn't exceed market configured limits + * @dev - the account has enough margin to cover for the fees + * @dev - the account has enough margin to not be liquidable immediately after the order is settled + * @dev if the order can be executed, it returns (newPosition, orderFees, fillPrice, oldPosition) + */ function validateOrder( Data storage order, SettlementStrategy.Data storage strategy, uint256 orderPrice - ) - internal - returns ( - // return pnl - Position.Data memory, - uint, - uint, - Position.Data storage oldPosition - ) - { + ) internal returns (Position.Data memory, uint, uint, Position.Data storage oldPosition) { if (order.sizeDelta == 0) { revert ZeroSizeOrder(); } @@ -286,6 +380,9 @@ library AsyncOrder { return (runtime.newPosition, runtime.orderFees, runtime.fillPrice, oldPosition); } + /** + * @notice Calculates the order fees. + */ function calculateOrderFee( int128 sizeDelta, uint256 fillPrice, @@ -330,6 +427,9 @@ library AsyncOrder { return takerFee + makerFee; } + /** + * @notice Calculates the fill price for an order. + */ function calculateFillPrice( int skew, uint skewScale, diff --git a/markets/perps-market/contracts/storage/GlobalPerpsMarket.sol b/markets/perps-market/contracts/storage/GlobalPerpsMarket.sol index e0f0fe36a2..36dd7a74a8 100644 --- a/markets/perps-market/contracts/storage/GlobalPerpsMarket.sol +++ b/markets/perps-market/contracts/storage/GlobalPerpsMarket.sol @@ -10,9 +10,9 @@ import {PerpsMarketFactory} from "./PerpsMarketFactory.sol"; import {PerpsPrice} from "./PerpsPrice.sol"; import {ISpotMarketSystem} from "../interfaces/external/ISpotMarketSystem.sol"; -/* - Note: This library contains all global perps market data -*/ +/** + * @title This library contains all global perps market data + */ library GlobalPerpsMarket { using SafeCastI256 for int256; using SafeCastU256 for uint256; @@ -22,18 +22,34 @@ library GlobalPerpsMarket { bytes32 private constant _SLOT_GLOBAL_PERPS_MARKET = keccak256(abi.encode("io.synthetix.perps-market.GlobalPerpsMarket")); + /** + * @notice Thrown when attempting to deposit more than enabled collateral. + */ error MaxCollateralExceeded( uint128 synthMarketId, uint maxAmount, uint collateralAmount, uint depositAmount ); + + /** + * @notice Thrown when attempting to use a synth that is not enabled as collateral. + */ error SynthNotEnabledForCollateral(uint128 synthMarketId); + + /** + * @notice Thrown when attempting to withdraw more collateral than is available. + */ error InsufficientCollateral(uint128 synthMarketId, uint collateralAmount, uint withdrawAmount); struct Data { + /** + * @dev Set of liquidatable account ids. + */ SetUtil.UintSet liquidatableAccounts; - // collateral amounts running total + /** + * @dev Collateral amounts running total, by collateral synth market id. + */ mapping(uint128 => uint) collateralAmounts; SetUtil.UintSet activeCollateralTypes; SetUtil.UintSet activeMarkets; @@ -81,16 +97,21 @@ library GlobalPerpsMarket { } } + /** + * @notice Check if the account is set as liquidatable. + */ function checkLiquidation(Data storage self, uint128 accountId) internal view { if (self.liquidatableAccounts.contains(accountId)) { revert PerpsAccount.AccountLiquidatable(accountId); } } - /* - 1. checks to ensure max cap isn't hit - 2. adjusts accounting for collateral amounts - */ + /** + * @notice Check the collateral is enabled and amount acceptable and adjusts accounting. + * @dev called when the account is modifying collateral. + * @dev 1. checks to ensure max cap isn't hit + * @dev 2. adjusts accounting for collateral amounts + */ function validateCollateralAmount( Data storage self, uint128 synthMarketId, diff --git a/markets/perps-market/contracts/storage/GlobalPerpsMarketConfiguration.sol b/markets/perps-market/contracts/storage/GlobalPerpsMarketConfiguration.sol index 19416c8884..12972e3037 100644 --- a/markets/perps-market/contracts/storage/GlobalPerpsMarketConfiguration.sol +++ b/markets/perps-market/contracts/storage/GlobalPerpsMarketConfiguration.sol @@ -3,9 +3,9 @@ pragma solidity >=0.8.11 <0.9.0; import {MathUtil} from "../utils/MathUtil.sol"; -/* - Note: This library contains all global perps market configuration data -*/ +/** + * @title This library contains all global perps market configuration data + */ library GlobalPerpsMarketConfiguration { bytes32 private constant _SLOT_GLOBAL_PERPS_MARKET_CONFIGURATION = keccak256(abi.encode("io.synthetix.perps-market.GlobalPerpsMarketConfiguration")); diff --git a/markets/perps-market/contracts/storage/OrderFee.sol b/markets/perps-market/contracts/storage/OrderFee.sol index 7001474025..ba26076ec3 100644 --- a/markets/perps-market/contracts/storage/OrderFee.sol +++ b/markets/perps-market/contracts/storage/OrderFee.sol @@ -1,9 +1,18 @@ //SPDX-License-Identifier: MIT pragma solidity >=0.8.11 <0.9.0; +/** + * @title Orders Fee data + */ library OrderFee { struct Data { + /** + * @dev Maker fee. Applied when order (or partial order) is reducing skew. + */ uint256 makerFee; + /** + * @dev Taker fee. Applied when order (or partial order) is increasing skew. + */ uint256 takerFee; } } From 9ac32ae76fe9fe392c7e85ccf4929e79e9fa2841 Mon Sep 17 00:00:00 2001 From: Noah Litvin <335975+noahlitvin@users.noreply.github.com> Date: Tue, 25 Jul 2023 07:39:21 -0400 Subject: [PATCH 11/63] SIP-328 * init * test: getMarketPools and getMarketPoolDebtDistribution --------- Co-authored-by: Peiman <25097709+Rickk137@users.noreply.github.com> Co-authored-by: Peiman --- .../interfaces/IMarketManagerModule.sol | 9 ++ .../modules/core/MarketManagerModule.sol | 53 ++++++++ .../synthetix/contracts/storage/Vault.sol | 2 +- .../modules/core/MarketManagerModule.test.ts | 113 ++++++++++++++++++ 4 files changed, 176 insertions(+), 1 deletion(-) diff --git a/protocol/synthetix/contracts/interfaces/IMarketManagerModule.sol b/protocol/synthetix/contracts/interfaces/IMarketManagerModule.sol index 7d37b0f54a..a4ae176ebc 100644 --- a/protocol/synthetix/contracts/interfaces/IMarketManagerModule.sol +++ b/protocol/synthetix/contracts/interfaces/IMarketManagerModule.sol @@ -228,4 +228,13 @@ interface IMarketManagerModule { * @return minRatioD18 The current market-specific minimum liquidity ratio, denominated with 18 decimals of precision. (100% is represented by 1 followed by 18 zeros.) */ function getMinLiquidityRatio(uint128 marketId) external view returns (uint256 minRatioD18); + + function getMarketPools( + uint128 marketId + ) external returns (uint128[] memory inRangePoolIds, uint128[] memory outRangePoolIds); + + function getMarketPoolDebtDistribution( + uint128 marketId, + uint128 poolId + ) external returns (uint256 sharesD18, uint128 totalSharesD18, int128 valuePerShareD27); } diff --git a/protocol/synthetix/contracts/modules/core/MarketManagerModule.sol b/protocol/synthetix/contracts/modules/core/MarketManagerModule.sol index 2304cc7c9f..47714ab81e 100644 --- a/protocol/synthetix/contracts/modules/core/MarketManagerModule.sol +++ b/protocol/synthetix/contracts/modules/core/MarketManagerModule.sol @@ -9,10 +9,12 @@ import "@synthetixio/core-contracts/contracts/errors/AccessError.sol"; import "@synthetixio/core-contracts/contracts/ownership/OwnableStorage.sol"; import "@synthetixio/core-contracts/contracts/utils/SafeCast.sol"; import "@synthetixio/core-contracts/contracts/utils/ERC165Helper.sol"; +import "@synthetixio/core-contracts/contracts/utils/HeapUtil.sol"; import "../../storage/Config.sol"; import "../../storage/Market.sol"; import "../../storage/MarketCreator.sol"; +import "../../storage/Distribution.sol"; import "@synthetixio/core-modules/contracts/storage/AssociatedSystem.sol"; import "@synthetixio/core-modules/contracts/storage/FeatureFlag.sol"; @@ -30,6 +32,8 @@ contract MarketManagerModule is IMarketManagerModule { using SafeCastI256 for int256; using Market for Market.Data; using AssociatedSystem for AssociatedSystem.Data; + using Distribution for Distribution.Data; + using HeapUtil for HeapUtil.Data; using DecimalMath for uint256; @@ -111,6 +115,55 @@ contract MarketManagerModule is IMarketManagerModule { return market.getDebtPerShare(); } + /** + * @inheritdoc IMarketManagerModule + */ + function getMarketPools( + uint128 marketId + ) + external + override + returns (uint128[] memory inRangePoolIds, uint128[] memory outRangePoolIds) + { + Market.Data storage market = Market.load(marketId); + market.distributeDebtToPools(999999999); + + HeapUtil.Data storage inRangePools = market.inRangePools; + inRangePoolIds = new uint128[](inRangePools.size()); + for (uint i = 1; i <= inRangePools.size(); i++) { + HeapUtil.Node memory node = inRangePools.getByIndex(i); + inRangePoolIds[i - 1] = node.id; + } + + HeapUtil.Data storage outRangePools = market.outRangePools; + outRangePoolIds = new uint128[](outRangePools.size()); + for (uint i = 1; i <= outRangePools.size(); i++) { + HeapUtil.Node memory node = outRangePools.getByIndex(i); + outRangePoolIds[i - 1] = node.id; + } + } + + /** + * @inheritdoc IMarketManagerModule + */ + function getMarketPoolDebtDistribution( + uint128 marketId, + uint128 poolId + ) + external + override + returns (uint256 sharesD18, uint128 totalSharesD18, int128 valuePerShareD27) + { + Market.Data storage market = Market.load(marketId); + market.distributeDebtToPools(999999999); + + Distribution.Data storage poolDistribution = market.poolsDebtDistribution; + sharesD18 = poolDistribution.getActorShares(poolId.toBytes32()); + + totalSharesD18 = market.poolsDebtDistribution.totalSharesD18; + valuePerShareD27 = market.poolsDebtDistribution.valuePerShareD27; + } + /** * @inheritdoc IMarketManagerModule */ diff --git a/protocol/synthetix/contracts/storage/Vault.sol b/protocol/synthetix/contracts/storage/Vault.sol index 6ff9e52cc9..bd73f80824 100644 --- a/protocol/synthetix/contracts/storage/Vault.sol +++ b/protocol/synthetix/contracts/storage/Vault.sol @@ -85,7 +85,7 @@ library Vault { function updateCreditCapacity( Data storage self, uint256 collateralPriceD18 - ) internal returns (uint256 usdWeightD18, int256 totalDebtD18) { + ) internal view returns (uint256 usdWeightD18, int256 totalDebtD18) { VaultEpoch.Data storage epochData = currentEpoch(self); usdWeightD18 = (epochData.collateralAmounts.totalAmount()).mulDecimal(collateralPriceD18); diff --git a/protocol/synthetix/test/integration/modules/core/MarketManagerModule.test.ts b/protocol/synthetix/test/integration/modules/core/MarketManagerModule.test.ts index a7f8531d54..95da5b8a0a 100644 --- a/protocol/synthetix/test/integration/modules/core/MarketManagerModule.test.ts +++ b/protocol/synthetix/test/integration/modules/core/MarketManagerModule.test.ts @@ -9,6 +9,7 @@ import { bootstrapWithMockMarketAndPool } from '../../bootstrap'; import { MockMarket__factory } from '../../../../typechain-types/index'; import { verifyUsesFeatureFlag } from '../../verifications'; import { snapshotCheckpoint } from '@synthetixio/core-utils/utils/mocha/snapshot'; +import { bn } from '../../../common'; describe('MarketManagerModule', function () { const { @@ -572,4 +573,116 @@ describe('MarketManagerModule', function () { }); }); }); + + describe('getMarketPools()', () => { + before(restore); + + before('add more staked pools', async () => { + // want a total of 3 staked pools + // create + await systems() + .Core.connect(owner) + .createPool(poolId + 1, await owner.getAddress()); + await systems() + .Core.connect(owner) + .createPool(poolId + 2, await owner.getAddress()); + + // configure + await systems() + .Core.connect(owner) + .setPoolConfiguration(poolId, [ + { + marketId: marketId(), + weightD18: ethers.utils.parseEther('1'), + maxDebtShareValueD18: ethers.utils.parseEther('0.1'), + }, + ]); + await systems() + .Core.connect(owner) + .setPoolConfiguration(poolId + 1, [ + { + marketId: marketId(), + weightD18: ethers.utils.parseEther('1'), + maxDebtShareValueD18: ethers.utils.parseEther('0.2'), + }, + ]); + await systems() + .Core.connect(owner) + .setPoolConfiguration(poolId + 2, [ + { + marketId: marketId(), + weightD18: ethers.utils.parseEther('1'), + maxDebtShareValueD18: ethers.utils.parseEther('0.3'), + }, + ]); + + // delegate + await systems() + .Core.connect(user1) + .delegateCollateral( + accountId, + poolId + 1, + collateralAddress(), + depositAmount, + ethers.utils.parseEther('1') + ); + + await systems() + .Core.connect(user1) + .delegateCollateral( + accountId, + poolId + 2, + collateralAddress(), + depositAmount, + ethers.utils.parseEther('1') + ); + }); + + it('inRangePools and outRangePools are returned correctly', async () => { + const result = await systems().Core.callStatic.getMarketPools(marketId()); + + assert.equal(result.inRangePoolIds.length, 3); + assert.equal(result.outRangePoolIds.length, 0); + }); + + it('distribute massive debt', async () => { + await MockMarket().connect(owner).setReportedDebt(bn(10000000000000)); + }); + + it('inRangePools and outRangePools are returned correctly', async () => { + const result = await systems().Core.callStatic.getMarketPools(marketId()); + assert.equal(result.inRangePoolIds.length, 0); + assert.equal(result.outRangePoolIds.length, 3); + }); + }); + + describe('getMarketPoolDebtDistribution()', () => { + before(restore); + + it('getMarketPoolDebtDistribution returns expected result', async () => { + const result = await systems().Core.callStatic.getMarketPoolDebtDistribution( + marketId(), + poolId + ); + + assertBn.equal(result.sharesD18, bn(1000)); + assertBn.equal(result.totalSharesD18, bn(1000)); + assertBn.equal(result.valuePerShareD27, bn(0)); + }); + + it('distribute massive debt', async () => { + await MockMarket().connect(owner).setReportedDebt(bn(10000000000000)); + }); + + it('getMarketPoolDebtDistribution returns expected result', async () => { + const result = await systems().Core.callStatic.getMarketPoolDebtDistribution( + marketId(), + poolId + ); + + assertBn.equal(result.sharesD18, bn(0)); + assertBn.equal(result.totalSharesD18, bn(0)); + assertBn.equal(result.valuePerShareD27, bn(1000000000)); + }); + }); }); From 5beb81993db0ef0f61fd48731202be18e80805f2 Mon Sep 17 00:00:00 2001 From: Noah Litvin <335975+noahlitvin@users.noreply.github.com> Date: Tue, 25 Jul 2023 10:24:54 -0400 Subject: [PATCH 12/63] depositing stablecoin default false (#1727) --- protocol/synthetix/cannonfile.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/protocol/synthetix/cannonfile.toml b/protocol/synthetix/cannonfile.toml index 92e965d29c..084e1b5434 100644 --- a/protocol/synthetix/cannonfile.toml +++ b/protocol/synthetix/cannonfile.toml @@ -279,7 +279,7 @@ fromCall.func = "owner" func = "configureCollateral" args = [ - { tokenAddress = "<%= contracts.USDProxy.address %>", oracleNodeId = "<%= extras.const_one_oracle_id %>", issuanceRatioD18 = "<%= parseEther('10') %>", liquidationRatioD18 = "<%= parseEther('10') %>", liquidationRewardD18 = "0", minDelegationD18 = "<%= MaxUint256 %>", depositingEnabled = true } + { tokenAddress = "<%= contracts.USDProxy.address %>", oracleNodeId = "<%= extras.const_one_oracle_id %>", issuanceRatioD18 = "<%= parseEther('10') %>", liquidationRatioD18 = "<%= parseEther('10') %>", liquidationRewardD18 = "0", minDelegationD18 = "<%= MaxUint256 %>", depositingEnabled = false } ] -depends = ["invoke.register_const_one_oracle", "invoke.init_usd"] \ No newline at end of file +depends = ["invoke.register_const_one_oracle", "invoke.init_usd"] From 786b7650d57f4bc423a080990786a95497f5c45f Mon Sep 17 00:00:00 2001 From: Daniel Beal Date: Wed, 26 Jul 2023 11:00:48 -0700 Subject: [PATCH 13/63] add ability to specify pool collateral configuration in particular, the ability to limit the amounto f collateral thats deposited to a pool --- .../contracts/interfaces/IPoolModule.sol | 9 +++++++ .../contracts/modules/core/PoolModule.sol | 7 ++++++ .../contracts/modules/core/VaultModule.sol | 5 ++++ protocol/synthetix/contracts/storage/Pool.sol | 23 ++++++++++++++++++ .../storage/PoolCollateralConfiguration.sol | 11 +++++++++ .../modules/core/VaultModule.test.ts | 24 +++++++++++++++++++ 6 files changed, 79 insertions(+) create mode 100644 protocol/synthetix/contracts/storage/PoolCollateralConfiguration.sol diff --git a/protocol/synthetix/contracts/interfaces/IPoolModule.sol b/protocol/synthetix/contracts/interfaces/IPoolModule.sol index bda29dccfd..5bbc0846f3 100644 --- a/protocol/synthetix/contracts/interfaces/IPoolModule.sol +++ b/protocol/synthetix/contracts/interfaces/IPoolModule.sol @@ -2,6 +2,7 @@ pragma solidity >=0.8.11 <0.9.0; import "../storage/MarketConfiguration.sol"; +import "../storage/PoolCollateralConfiguration.sol"; /** * @title Module for the creation and management of pools. @@ -99,6 +100,14 @@ interface IPoolModule { MarketConfiguration.Data[] memory marketDistribution ) external; + /** + * @notice Allows the pool owner to set the configuration of a specific collateral type for their pool. + * @param poolId The id of the pool whose configuration is being set. + * @param collateralType The collate + * @param newConfig The config to set + */ + function setPoolCollateralConfiguration(uint128 poolId, address collateralType, PoolCollateralConfiguration.Data memory newConfig) external; + /** * @notice Retrieves the MarketConfiguration of the specified pool. * @param poolId The id of the pool whose configuration is being queried. diff --git a/protocol/synthetix/contracts/modules/core/PoolModule.sol b/protocol/synthetix/contracts/modules/core/PoolModule.sol index 93bed43105..01c03017e8 100644 --- a/protocol/synthetix/contracts/modules/core/PoolModule.sol +++ b/protocol/synthetix/contracts/modules/core/PoolModule.sol @@ -197,6 +197,13 @@ contract PoolModule is IPoolModule { emit PoolConfigurationSet(poolId, newMarketConfigurations, msg.sender); } + function setPoolCollateralConfiguration(uint128 poolId, address collateralType, PoolCollateralConfiguration.Data memory newConfig) external override { + Pool.Data storage pool = Pool.loadExisting(poolId); + Pool.onlyPoolOwner(poolId, msg.sender); + + pool.collateralConfigurations[collateralType] = newConfig; + } + /** * @inheritdoc IPoolModule */ diff --git a/protocol/synthetix/contracts/modules/core/VaultModule.sol b/protocol/synthetix/contracts/modules/core/VaultModule.sol index defd791dfd..86681c1307 100644 --- a/protocol/synthetix/contracts/modules/core/VaultModule.sol +++ b/protocol/synthetix/contracts/modules/core/VaultModule.sol @@ -85,6 +85,11 @@ contract VaultModule is IVaultModule { newCollateralAmountD18 - currentCollateralAmount ); + Pool.loadExisting(poolId).requireSufficientCollateralCapacity( + collateralType, + newCollateralAmountD18 - currentCollateralAmount + ); + // if decreasing delegation amount, ensure min time has elapsed } else { Pool.loadExisting(poolId).requireMinDelegationTimeElapsed( diff --git a/protocol/synthetix/contracts/storage/Pool.sol b/protocol/synthetix/contracts/storage/Pool.sol index 565d568ab8..9afb2aeed4 100644 --- a/protocol/synthetix/contracts/storage/Pool.sol +++ b/protocol/synthetix/contracts/storage/Pool.sol @@ -6,6 +6,7 @@ import "./Distribution.sol"; import "./MarketConfiguration.sol"; import "./Vault.sol"; import "./Market.sol"; +import "./PoolCollateralConfiguration.sol"; import "./SystemPoolConfiguration.sol"; import "@synthetixio/core-contracts/contracts/errors/AccessError.sol"; @@ -48,6 +49,11 @@ library Pool { */ error MinDelegationTimeoutPending(uint128 poolId, uint32 timeRemaining); + /** + * @dev Thrown when pool has surpassed max collateral deposit + */ + error SurpassedPoolMaxCollateralDeposit(uint128 poolId, address collateralType, uint256 currentCollateral, uint256 maxCollateral); + bytes32 private constant _CONFIG_SET_MARKET_MIN_DELEGATE_MAX = "setMarketMinDelegateTime_max"; struct Data { @@ -113,6 +119,8 @@ library Pool { uint64 __reserved1; uint64 __reserved2; uint64 __reserved3; + + mapping(address => PoolCollateralConfiguration.Data) collateralConfigurations; } /** @@ -507,4 +515,19 @@ library Pool { ); } } + + function requireSufficientCollateralCapacity( + Data storage self, + address collateralType, + uint256 collateralAmountD18 + ) internal view { + uint256 maxDeposit = self.collateralConfigurations[collateralType].maxDepositD18; + + if ( + maxDeposit > 0 && + self.vaults[collateralType].currentCollateral() + collateralAmountD18 > maxDeposit + ) { + revert SurpassedPoolMaxCollateralDeposit(self.id, collateralType, self.vaults[collateralType].currentCollateral() + collateralAmountD18, self.collateralConfigurations[collateralType].maxDepositD18); + } + } } diff --git a/protocol/synthetix/contracts/storage/PoolCollateralConfiguration.sol b/protocol/synthetix/contracts/storage/PoolCollateralConfiguration.sol new file mode 100644 index 0000000000..044b830953 --- /dev/null +++ b/protocol/synthetix/contracts/storage/PoolCollateralConfiguration.sol @@ -0,0 +1,11 @@ +//SPDX-License-Identifier: MIT +pragma solidity >=0.8.11 <0.9.0; + +library PoolCollateralConfiguration { + bytes32 private constant _SLOT = + keccak256(abi.encode("io.synthetix.synthetix.PoolCollateralConfiguration")); + + struct Data { + uint256 maxDepositD18; + } +} diff --git a/protocol/synthetix/test/integration/modules/core/VaultModule.test.ts b/protocol/synthetix/test/integration/modules/core/VaultModule.test.ts index d73c2354a2..dc290dc5a4 100644 --- a/protocol/synthetix/test/integration/modules/core/VaultModule.test.ts +++ b/protocol/synthetix/test/integration/modules/core/VaultModule.test.ts @@ -314,6 +314,30 @@ describe('VaultModule', function () { }); }); + describe('when pool has limited collateral deposit', async () => { + before('set pool limit', async () => { + await systems() + .Core.connect(owner) + .setPoolCollateralConfiguration(poolId, collateralAddress(), { maxDepositD18: depositAmount.div(2) }); + }); + + it.only('fails when pool does not allow sufficient deposit amount', async () => { + await assertRevert( + systems() + .Core.connect(user1) + .delegateCollateral( + accountId, + poolId, + collateralAddress(), + depositAmount.mul(2), + ethers.utils.parseEther('1') + ), + `SurpassedPoolMaxCollateralDeposit("${poolId}", "${collateralAddress()}", "${depositAmount.mul(2).toString()}", "${depositAmount.div(2).toString()}")`, + systems().Core + ); + }); + }); + it( 'user1 has expected initial position', verifyAccountState(accountId, poolId, depositAmount, 0) From e9c9e2ac264212ffe57e58c97d55b97a32b51d0e Mon Sep 17 00:00:00 2001 From: Daniel Beal Date: Wed, 26 Jul 2023 14:42:09 -0700 Subject: [PATCH 14/63] ability to pass runtime values into oracle manager nodes they can be passed as an array of keys and values. a simple loop looking over all the keys can find any necessary . an example of how this could be used is for an external node to check to see what the volume of a particular order is, to modify the oracle's resulting value based on the calculation. --- .../contracts/interfaces/INodeModule.sol | 9 +++++ .../interfaces/external/IExternalNode.sol | 4 ++- .../contracts/mocks/MockExternalNode.sol | 13 ++++++-- .../contracts/modules/NodeModule.sol | 19 +++++++++-- .../contracts/nodes/ExternalNode.sol | 6 ++-- .../integration/nodes/ExternalNode.test.ts | 33 +++++++++++++++++++ 6 files changed, 76 insertions(+), 8 deletions(-) diff --git a/protocol/oracle-manager/contracts/interfaces/INodeModule.sol b/protocol/oracle-manager/contracts/interfaces/INodeModule.sol index 89558f8642..bf7753bc70 100644 --- a/protocol/oracle-manager/contracts/interfaces/INodeModule.sol +++ b/protocol/oracle-manager/contracts/interfaces/INodeModule.sol @@ -74,4 +74,13 @@ interface INodeModule { * @return node The node's output data */ function process(bytes32 nodeId) external view returns (NodeOutput.Data memory node); + + /** + * @notice Returns a node current output data + * @param nodeId The node ID + * @param runtimeKeys Keys corresponding to runtime values which could be used by the node graph + * @param runtimeValues The values used by the node graph + * @return node The node's output data + */ + function processWithRuntime(bytes32 nodeId, bytes32[] memory runtimeKeys, bytes32[] memory runtimeValues) external view returns (NodeOutput.Data memory node); } diff --git a/protocol/oracle-manager/contracts/interfaces/external/IExternalNode.sol b/protocol/oracle-manager/contracts/interfaces/external/IExternalNode.sol index 8ce8089425..a99e528713 100644 --- a/protocol/oracle-manager/contracts/interfaces/external/IExternalNode.sol +++ b/protocol/oracle-manager/contracts/interfaces/external/IExternalNode.sol @@ -10,7 +10,9 @@ import "../../storage/NodeDefinition.sol"; interface IExternalNode is IERC165 { function process( NodeOutput.Data[] memory parentNodeOutputs, - bytes memory parameters + bytes memory parameters, + bytes32[] memory runtimeKeys, + bytes32[] memory runtimeValuess ) external view returns (NodeOutput.Data memory); function isValid(NodeDefinition.Data memory nodeDefinition) external returns (bool); diff --git a/protocol/oracle-manager/contracts/mocks/MockExternalNode.sol b/protocol/oracle-manager/contracts/mocks/MockExternalNode.sol index 1233f17c21..0b829741f8 100644 --- a/protocol/oracle-manager/contracts/mocks/MockExternalNode.sol +++ b/protocol/oracle-manager/contracts/mocks/MockExternalNode.sol @@ -13,9 +13,18 @@ contract MockExternalNode is IExternalNode { function process( NodeOutput.Data[] memory, - bytes memory + bytes memory, + bytes32[] memory runtimeKeys, + bytes32[] memory runtimeValues ) external view override returns (NodeOutput.Data memory) { - return output; + NodeOutput.Data memory theOutput = output; + + for (uint256 i = 0; i < runtimeKeys.length; i++) { + if (runtimeKeys[i] == "overridePrice") { + theOutput.price = int256(uint256(runtimeValues[i])); + } + } + return theOutput; } function isValid( diff --git a/protocol/oracle-manager/contracts/modules/NodeModule.sol b/protocol/oracle-manager/contracts/modules/NodeModule.sol index 115cde6aad..ed1522878e 100644 --- a/protocol/oracle-manager/contracts/modules/NodeModule.sol +++ b/protocol/oracle-manager/contracts/modules/NodeModule.sol @@ -64,7 +64,18 @@ contract NodeModule is INodeModule { * @inheritdoc INodeModule */ function process(bytes32 nodeId) external view returns (NodeOutput.Data memory node) { - return _process(nodeId); + return _process(nodeId, new bytes32[](0), new bytes32[](0)); + } + + /** + * @inheritdoc INodeModule + */ + function processWithRuntime(bytes32 nodeId, bytes32[] memory runtimeKeys, bytes32[] memory runtimeValues) + external + view + returns (NodeOutput.Data memory node) + { + return _process(nodeId, runtimeKeys, runtimeValues); } /** @@ -135,7 +146,7 @@ contract NodeModule is INodeModule { /** * @dev Returns the output of a specified node. */ - function _process(bytes32 nodeId) internal view returns (NodeOutput.Data memory price) { + function _process(bytes32 nodeId, bytes32[] memory runtimeKeys, bytes32[] memory runtimeValues) internal view returns (NodeOutput.Data memory price) { NodeDefinition.Data memory nodeDefinition = NodeDefinition.load(nodeId); if (nodeDefinition.nodeType == NodeDefinition.NodeType.REDUCER) { @@ -148,7 +159,9 @@ contract NodeModule is INodeModule { return ExternalNode.process( _processParentNodeOutputs(nodeDefinition), - nodeDefinition.parameters + nodeDefinition.parameters, + runtimeKeys, + runtimeValues ); } else if (nodeDefinition.nodeType == NodeDefinition.NodeType.CHAINLINK) { return ChainlinkNode.process(nodeDefinition.parameters); diff --git a/protocol/oracle-manager/contracts/nodes/ExternalNode.sol b/protocol/oracle-manager/contracts/nodes/ExternalNode.sol index 3441bc64b9..2a102ea1be 100644 --- a/protocol/oracle-manager/contracts/nodes/ExternalNode.sol +++ b/protocol/oracle-manager/contracts/nodes/ExternalNode.sol @@ -10,10 +10,12 @@ import "../interfaces/external/IExternalNode.sol"; library ExternalNode { function process( NodeOutput.Data[] memory prices, - bytes memory parameters + bytes memory parameters, + bytes32[] memory runtimeKeys, + bytes32[] memory runtimeValues ) internal view returns (NodeOutput.Data memory nodeOutput) { IExternalNode externalNode = IExternalNode(abi.decode(parameters, (address))); - return externalNode.process(prices, parameters); + return externalNode.process(prices, parameters, runtimeKeys, runtimeValues); } function isValid(NodeDefinition.Data memory nodeDefinition) internal returns (bool valid) { diff --git a/protocol/oracle-manager/test/integration/nodes/ExternalNode.test.ts b/protocol/oracle-manager/test/integration/nodes/ExternalNode.test.ts index 6eb7f1ac15..8c132d8f5a 100644 --- a/protocol/oracle-manager/test/integration/nodes/ExternalNode.test.ts +++ b/protocol/oracle-manager/test/integration/nodes/ExternalNode.test.ts @@ -46,6 +46,39 @@ describe('ExternalNode', function () { assertBn.equal(output.timestamp, timestamp); }); + it('works with runtimeKeys and runtimeValues', async () => { + const [owner] = getSigners(); + const price = 100; + const timestamp = 200; + + // Deploy the mock + const factory = await hre.ethers.getContractFactory('MockExternalNode'); + const ValidExternalNode = await factory.connect(owner).deploy(price, timestamp); + + // Register the mock + const NodeParameters = abi.encode(['address'], [ValidExternalNode.address]); + const tx = await NodeModule.registerNode( + NodeTypes.EXTERNAL, + NodeParameters, + [] + ); + const receipt = await tx.wait(); + const event = findSingleEvent({ + receipt, + eventName: 'NodeRegistered', + }); + + // Verify the registration event data + const nodeId = event.args.nodeId; + assert.equal(event.args.nodeType, NodeTypes.EXTERNAL); + assert.equal(event.args.parameters, NodeParameters); + + // Verify the node processes output as expected + const output = await NodeModule.processWithRuntime(nodeId, [ethers.utils.formatBytes32String('overridePrice')], [ethers.utils.hexZeroPad(ethers.BigNumber.from('100').toHexString(), 32)]); + assertBn.equal(output.price, ethers.BigNumber.from('100')); + assertBn.equal(output.timestamp, timestamp); + }); + it('cannot be registered if it does not conform to the IExternalNode interface.', async () => { const [owner] = getSigners(); const factory = await hre.ethers.getContractFactory('MockChainlinkAggregator'); From afc116e2184b1b070f4866c60452035e6f8e4b12 Mon Sep 17 00:00:00 2001 From: Daniel Beal Date: Wed, 26 Jul 2023 14:47:37 -0700 Subject: [PATCH 15/63] lint fix --- .../contracts/interfaces/INodeModule.sol | 6 +++++- .../contracts/mocks/MockExternalNode.sol | 1 + .../contracts/modules/NodeModule.sol | 16 ++++++++++------ .../test/integration/nodes/ExternalNode.test.ts | 12 ++++++------ .../contracts/interfaces/IPoolModule.sol | 6 +++++- .../contracts/modules/core/PoolModule.sol | 6 +++++- protocol/synthetix/contracts/storage/Pool.sol | 15 ++++++++++++--- .../integration/modules/core/VaultModule.test.ts | 10 +++++++--- 8 files changed, 51 insertions(+), 21 deletions(-) diff --git a/protocol/oracle-manager/contracts/interfaces/INodeModule.sol b/protocol/oracle-manager/contracts/interfaces/INodeModule.sol index bf7753bc70..eedb18d378 100644 --- a/protocol/oracle-manager/contracts/interfaces/INodeModule.sol +++ b/protocol/oracle-manager/contracts/interfaces/INodeModule.sol @@ -82,5 +82,9 @@ interface INodeModule { * @param runtimeValues The values used by the node graph * @return node The node's output data */ - function processWithRuntime(bytes32 nodeId, bytes32[] memory runtimeKeys, bytes32[] memory runtimeValues) external view returns (NodeOutput.Data memory node); + function processWithRuntime( + bytes32 nodeId, + bytes32[] memory runtimeKeys, + bytes32[] memory runtimeValues + ) external view returns (NodeOutput.Data memory node); } diff --git a/protocol/oracle-manager/contracts/mocks/MockExternalNode.sol b/protocol/oracle-manager/contracts/mocks/MockExternalNode.sol index 0b829741f8..f428e7631f 100644 --- a/protocol/oracle-manager/contracts/mocks/MockExternalNode.sol +++ b/protocol/oracle-manager/contracts/mocks/MockExternalNode.sol @@ -21,6 +21,7 @@ contract MockExternalNode is IExternalNode { for (uint256 i = 0; i < runtimeKeys.length; i++) { if (runtimeKeys[i] == "overridePrice") { + // solhint-disable-next-line numcast/safe-cast theOutput.price = int256(uint256(runtimeValues[i])); } } diff --git a/protocol/oracle-manager/contracts/modules/NodeModule.sol b/protocol/oracle-manager/contracts/modules/NodeModule.sol index ed1522878e..5670706d5a 100644 --- a/protocol/oracle-manager/contracts/modules/NodeModule.sol +++ b/protocol/oracle-manager/contracts/modules/NodeModule.sol @@ -70,11 +70,11 @@ contract NodeModule is INodeModule { /** * @inheritdoc INodeModule */ - function processWithRuntime(bytes32 nodeId, bytes32[] memory runtimeKeys, bytes32[] memory runtimeValues) - external - view - returns (NodeOutput.Data memory node) - { + function processWithRuntime( + bytes32 nodeId, + bytes32[] memory runtimeKeys, + bytes32[] memory runtimeValues + ) external view returns (NodeOutput.Data memory node) { return _process(nodeId, runtimeKeys, runtimeValues); } @@ -146,7 +146,11 @@ contract NodeModule is INodeModule { /** * @dev Returns the output of a specified node. */ - function _process(bytes32 nodeId, bytes32[] memory runtimeKeys, bytes32[] memory runtimeValues) internal view returns (NodeOutput.Data memory price) { + function _process( + bytes32 nodeId, + bytes32[] memory runtimeKeys, + bytes32[] memory runtimeValues + ) internal view returns (NodeOutput.Data memory price) { NodeDefinition.Data memory nodeDefinition = NodeDefinition.load(nodeId); if (nodeDefinition.nodeType == NodeDefinition.NodeType.REDUCER) { diff --git a/protocol/oracle-manager/test/integration/nodes/ExternalNode.test.ts b/protocol/oracle-manager/test/integration/nodes/ExternalNode.test.ts index 8c132d8f5a..bb5e524274 100644 --- a/protocol/oracle-manager/test/integration/nodes/ExternalNode.test.ts +++ b/protocol/oracle-manager/test/integration/nodes/ExternalNode.test.ts @@ -57,11 +57,7 @@ describe('ExternalNode', function () { // Register the mock const NodeParameters = abi.encode(['address'], [ValidExternalNode.address]); - const tx = await NodeModule.registerNode( - NodeTypes.EXTERNAL, - NodeParameters, - [] - ); + const tx = await NodeModule.registerNode(NodeTypes.EXTERNAL, NodeParameters, []); const receipt = await tx.wait(); const event = findSingleEvent({ receipt, @@ -74,7 +70,11 @@ describe('ExternalNode', function () { assert.equal(event.args.parameters, NodeParameters); // Verify the node processes output as expected - const output = await NodeModule.processWithRuntime(nodeId, [ethers.utils.formatBytes32String('overridePrice')], [ethers.utils.hexZeroPad(ethers.BigNumber.from('100').toHexString(), 32)]); + const output = await NodeModule.processWithRuntime( + nodeId, + [ethers.utils.formatBytes32String('overridePrice')], + [ethers.utils.hexZeroPad(ethers.BigNumber.from('100').toHexString(), 32)] + ); assertBn.equal(output.price, ethers.BigNumber.from('100')); assertBn.equal(output.timestamp, timestamp); }); diff --git a/protocol/synthetix/contracts/interfaces/IPoolModule.sol b/protocol/synthetix/contracts/interfaces/IPoolModule.sol index 5bbc0846f3..f17d55acb6 100644 --- a/protocol/synthetix/contracts/interfaces/IPoolModule.sol +++ b/protocol/synthetix/contracts/interfaces/IPoolModule.sol @@ -106,7 +106,11 @@ interface IPoolModule { * @param collateralType The collate * @param newConfig The config to set */ - function setPoolCollateralConfiguration(uint128 poolId, address collateralType, PoolCollateralConfiguration.Data memory newConfig) external; + function setPoolCollateralConfiguration( + uint128 poolId, + address collateralType, + PoolCollateralConfiguration.Data memory newConfig + ) external; /** * @notice Retrieves the MarketConfiguration of the specified pool. diff --git a/protocol/synthetix/contracts/modules/core/PoolModule.sol b/protocol/synthetix/contracts/modules/core/PoolModule.sol index 01c03017e8..f475ed1ace 100644 --- a/protocol/synthetix/contracts/modules/core/PoolModule.sol +++ b/protocol/synthetix/contracts/modules/core/PoolModule.sol @@ -197,7 +197,11 @@ contract PoolModule is IPoolModule { emit PoolConfigurationSet(poolId, newMarketConfigurations, msg.sender); } - function setPoolCollateralConfiguration(uint128 poolId, address collateralType, PoolCollateralConfiguration.Data memory newConfig) external override { + function setPoolCollateralConfiguration( + uint128 poolId, + address collateralType, + PoolCollateralConfiguration.Data memory newConfig + ) external override { Pool.Data storage pool = Pool.loadExisting(poolId); Pool.onlyPoolOwner(poolId, msg.sender); diff --git a/protocol/synthetix/contracts/storage/Pool.sol b/protocol/synthetix/contracts/storage/Pool.sol index 9afb2aeed4..5b152251bd 100644 --- a/protocol/synthetix/contracts/storage/Pool.sol +++ b/protocol/synthetix/contracts/storage/Pool.sol @@ -52,7 +52,12 @@ library Pool { /** * @dev Thrown when pool has surpassed max collateral deposit */ - error SurpassedPoolMaxCollateralDeposit(uint128 poolId, address collateralType, uint256 currentCollateral, uint256 maxCollateral); + error SurpassedPoolMaxCollateralDeposit( + uint128 poolId, + address collateralType, + uint256 currentCollateral, + uint256 maxCollateral + ); bytes32 private constant _CONFIG_SET_MARKET_MIN_DELEGATE_MAX = "setMarketMinDelegateTime_max"; @@ -119,7 +124,6 @@ library Pool { uint64 __reserved1; uint64 __reserved2; uint64 __reserved3; - mapping(address => PoolCollateralConfiguration.Data) collateralConfigurations; } @@ -527,7 +531,12 @@ library Pool { maxDeposit > 0 && self.vaults[collateralType].currentCollateral() + collateralAmountD18 > maxDeposit ) { - revert SurpassedPoolMaxCollateralDeposit(self.id, collateralType, self.vaults[collateralType].currentCollateral() + collateralAmountD18, self.collateralConfigurations[collateralType].maxDepositD18); + revert SurpassedPoolMaxCollateralDeposit( + self.id, + collateralType, + self.vaults[collateralType].currentCollateral() + collateralAmountD18, + self.collateralConfigurations[collateralType].maxDepositD18 + ); } } } diff --git a/protocol/synthetix/test/integration/modules/core/VaultModule.test.ts b/protocol/synthetix/test/integration/modules/core/VaultModule.test.ts index dc290dc5a4..864b4ab4ad 100644 --- a/protocol/synthetix/test/integration/modules/core/VaultModule.test.ts +++ b/protocol/synthetix/test/integration/modules/core/VaultModule.test.ts @@ -318,10 +318,12 @@ describe('VaultModule', function () { before('set pool limit', async () => { await systems() .Core.connect(owner) - .setPoolCollateralConfiguration(poolId, collateralAddress(), { maxDepositD18: depositAmount.div(2) }); + .setPoolCollateralConfiguration(poolId, collateralAddress(), { + maxDepositD18: depositAmount.div(2), + }); }); - it.only('fails when pool does not allow sufficient deposit amount', async () => { + it('fails when pool does not allow sufficient deposit amount', async () => { await assertRevert( systems() .Core.connect(user1) @@ -332,7 +334,9 @@ describe('VaultModule', function () { depositAmount.mul(2), ethers.utils.parseEther('1') ), - `SurpassedPoolMaxCollateralDeposit("${poolId}", "${collateralAddress()}", "${depositAmount.mul(2).toString()}", "${depositAmount.div(2).toString()}")`, + `SurpassedPoolMaxCollateralDeposit("${poolId}", "${collateralAddress()}", "${depositAmount + .mul(2) + .toString()}", "${depositAmount.div(2).toString()}")`, systems().Core ); }); From 83585c617e5b2724aed16d33b8eee24932bc489b Mon Sep 17 00:00:00 2001 From: Sunny Vempati Date: Thu, 27 Jul 2023 17:41:28 -0500 Subject: [PATCH 16/63] Liquidation tests (#1724) * add liq test * more liq test * liq events * market updated event * deposit fix * fix liq flagged * derived test values * remove unused * more tests * remove only * partial liq position fix * fix name --- .../interfaces/ILiquidationModule.sol | 9 + .../modules/AsyncOrderSettlementModule.sol | 9 +- .../contracts/modules/LiquidationModule.sol | 75 ++++- .../contracts/storage/PerpsAccount.sol | 91 +++--- .../contracts/storage/PerpsMarket.sol | 24 +- .../contracts/storage/PerpsMarketFactory.sol | 8 +- .../contracts/storage/Position.sol | 2 +- .../Liquidation/Liquidation.margin.test.ts | 16 +- .../Liquidation.multi-collateral.test.ts | 292 ++++++++++++++++++ .../bootstrap/bootstrapPerpsMarkets.ts | 6 +- .../test/integration/helpers/fillPrice.ts | 10 + 11 files changed, 458 insertions(+), 84 deletions(-) create mode 100644 markets/perps-market/test/integration/Liquidation/Liquidation.multi-collateral.test.ts diff --git a/markets/perps-market/contracts/interfaces/ILiquidationModule.sol b/markets/perps-market/contracts/interfaces/ILiquidationModule.sol index 672d85d18e..0dabb49e0d 100644 --- a/markets/perps-market/contracts/interfaces/ILiquidationModule.sol +++ b/markets/perps-market/contracts/interfaces/ILiquidationModule.sol @@ -4,6 +4,15 @@ pragma solidity >=0.8.11 <0.9.0; interface ILiquidationModule { error NotEligibleForLiquidation(uint128 accountId); + event PositionLiquidated( + uint128 indexed accountId, + uint128 indexed marketId, + uint256 amountLiquidated, + int128 currentPositionSize + ); + + event AccountLiquidated(uint128 indexed accountId, uint256 reward, bool fullLiquidation); + function liquidate(uint128 accountId) external; function liquidateFlagged() external; diff --git a/markets/perps-market/contracts/modules/AsyncOrderSettlementModule.sol b/markets/perps-market/contracts/modules/AsyncOrderSettlementModule.sol index 11b7877bc0..2378eccbbe 100644 --- a/markets/perps-market/contracts/modules/AsyncOrderSettlementModule.sol +++ b/markets/perps-market/contracts/modules/AsyncOrderSettlementModule.sol @@ -130,6 +130,9 @@ contract AsyncOrderSettlementModule is IAsyncOrderSettlementModule, IMarketEvent uint fillPrice, Position.Data storage oldPosition ) = asyncOrder.validateOrder(settlementStrategy, price); + + runtime.amountToDeduct += totalFees; + runtime.newPositionSize = newPosition.size; runtime.sizeDelta = asyncOrder.sizeDelta; @@ -143,7 +146,7 @@ contract AsyncOrderSettlementModule is IAsyncOrderSettlementModule, IMarketEvent if (runtime.pnl > 0) { perpsAccount.updateCollateralAmount(SNX_USD_MARKET_ID, runtime.pnl); } else if (runtime.pnl < 0) { - runtime.amountToDeduct = runtime.pnlUint; + runtime.amountToDeduct += runtime.pnlUint; } // after pnl is realized, update position @@ -164,7 +167,9 @@ contract AsyncOrderSettlementModule is IAsyncOrderSettlementModule, IMarketEvent // since margin is deposited, as long as the owed collateral is deducted // fees are realized by the stakers - perpsAccount.deductFromAccount(runtime.amountToDeduct + totalFees); + if (runtime.amountToDeduct > 0) { + perpsAccount.deductFromAccount(runtime.amountToDeduct); + } runtime.settlementReward = settlementStrategy.settlementReward; if (runtime.settlementReward > 0) { diff --git a/markets/perps-market/contracts/modules/LiquidationModule.sol b/markets/perps-market/contracts/modules/LiquidationModule.sol index 6f8e5ec641..ead4f1937f 100644 --- a/markets/perps-market/contracts/modules/LiquidationModule.sol +++ b/markets/perps-market/contracts/modules/LiquidationModule.sol @@ -1,16 +1,28 @@ //SPDX-License-Identifier: MIT pragma solidity >=0.8.11 <0.9.0; +import {DecimalMath} from "@synthetixio/core-contracts/contracts/utils/DecimalMath.sol"; import {SafeCastU256} from "@synthetixio/core-contracts/contracts/utils/SafeCast.sol"; import {SetUtil} from "@synthetixio/core-contracts/contracts/utils/SetUtil.sol"; import {ILiquidationModule} from "../interfaces/ILiquidationModule.sol"; import {PerpsAccount} from "../storage/PerpsAccount.sol"; +import {PerpsMarket} from "../storage/PerpsMarket.sol"; +import {PerpsPrice} from "../storage/PerpsPrice.sol"; +import {PerpsMarketFactory} from "../storage/PerpsMarketFactory.sol"; +import {GlobalPerpsMarketConfiguration} from "../storage/GlobalPerpsMarketConfiguration.sol"; +import {PerpsMarketConfiguration} from "../storage/PerpsMarketConfiguration.sol"; import {GlobalPerpsMarket} from "../storage/GlobalPerpsMarket.sol"; +import {IMarketEvents} from "../interfaces/IMarketEvents.sol"; -contract LiquidationModule is ILiquidationModule { +contract LiquidationModule is ILiquidationModule, IMarketEvents { + using DecimalMath for uint256; using SafeCastU256 for uint256; using SetUtil for SetUtil.UintSet; using PerpsAccount for PerpsAccount.Data; + using PerpsMarketConfiguration for PerpsMarketConfiguration.Data; + using GlobalPerpsMarket for GlobalPerpsMarket.Data; + using PerpsMarketFactory for PerpsMarketFactory.Data; + using GlobalPerpsMarketConfiguration for GlobalPerpsMarketConfiguration.Data; function liquidate(uint128 accountId) external override { SetUtil.UintSet storage liquidatableAccounts = GlobalPerpsMarket @@ -32,25 +44,68 @@ contract LiquidationModule is ILiquidationModule { } function liquidateFlagged() external override { - SetUtil.UintSet storage liquidatableAccounts = GlobalPerpsMarket + uint256[] memory liquidatableAccounts = GlobalPerpsMarket .load() - .liquidatableAccounts; + .liquidatableAccounts + .values(); - for (uint i = 0; i < liquidatableAccounts.length(); i++) { - uint128 accountId = liquidatableAccounts.valueAt(i).to128(); + for (uint i = 0; i < liquidatableAccounts.length; i++) { + uint128 accountId = liquidatableAccounts[i].to128(); _liquidateAccount(PerpsAccount.load(accountId)); } } function _liquidateAccount(PerpsAccount.Data storage account) internal { - account.liquidateAccount(); + uint128 accountId = account.id; + uint256[] memory openPositionMarketIds = account.openPositionMarketIds.values(); + + uint accumulatedLiquidationRewards; + + for (uint i = 0; i < openPositionMarketIds.length; i++) { + uint128 positionMarketId = openPositionMarketIds[i].to128(); + uint256 price = PerpsPrice.getCurrentPrice(positionMarketId); + + ( + uint256 amountLiquidated, + int128 newPositionSize, + int128 sizeDelta, + PerpsMarket.MarketUpdateData memory marketUpdateData + ) = account.liquidatePosition(positionMarketId, price); + + emit MarketUpdated( + positionMarketId, + price, + marketUpdateData.skew, + marketUpdateData.size, + sizeDelta, + marketUpdateData.currentFundingRate, + marketUpdateData.currentFundingVelocity + ); - // TODO: account can be removed from liquidation if the margin reqs are met, + emit PositionLiquidated(accountId, positionMarketId, amountLiquidated, newPositionSize); - if (account.openPositionMarketIds.length() == 0) { - GlobalPerpsMarket.load().liquidatableAccounts.remove(account.id); + // using amountToLiquidate to calculate liquidation reward + uint256 liquidationReward = PerpsMarketConfiguration + .load(positionMarketId) + .calculateLiquidationReward(amountLiquidated.mulDecimal(price)); + accumulatedLiquidationRewards += liquidationReward; } - // TODO: emit event + uint256 keeperLiquidationReward = _processLiquidationRewards(accumulatedLiquidationRewards); + + bool accountFullyLiquidated = account.openPositionMarketIds.length() == 0; + if (accountFullyLiquidated) { + GlobalPerpsMarket.load().liquidatableAccounts.remove(accountId); + } + + emit AccountLiquidated(accountId, keeperLiquidationReward, accountFullyLiquidated); + } + + function _processLiquidationRewards(uint256 totalRewards) private returns (uint256 reward) { + // pay out liquidation rewards + reward = GlobalPerpsMarketConfiguration.load().liquidationReward(totalRewards); + if (reward > 0) { + PerpsMarketFactory.load().withdrawMarketUsd(msg.sender, reward); + } } } diff --git a/markets/perps-market/contracts/storage/PerpsAccount.sol b/markets/perps-market/contracts/storage/PerpsAccount.sol index d25d393932..5695e18701 100644 --- a/markets/perps-market/contracts/storage/PerpsAccount.sol +++ b/markets/perps-market/contracts/storage/PerpsAccount.sol @@ -238,22 +238,21 @@ library PerpsAccount { function convertAllCollateralToUsd(Data storage self) internal { PerpsMarketFactory.Data storage factory = PerpsMarketFactory.load(); - SetUtil.UintSet storage activeCollateralTypes = self.activeCollateralTypes; - uint256 activeCollateralTypesLength = activeCollateralTypes.length(); + uint[] memory activeCollateralTypes = self.activeCollateralTypes.values(); // 1. withdraw all collateral from synthetix // 2. sell all collateral for snxUSD // 3. deposit snxUSD into synthetix - for (uint i = 1; i <= activeCollateralTypesLength; i++) { - uint128 synthMarketId = activeCollateralTypes.valueAt(i).to128(); - if (synthMarketId != SNX_USD_MARKET_ID) { - _deductAllSynth(self, factory, synthMarketId); - } else { + for (uint256 i = 0; i < activeCollateralTypes.length; i++) { + uint128 synthMarketId = activeCollateralTypes[i].to128(); + if (synthMarketId == SNX_USD_MARKET_ID) { updateCollateralAmount( self, synthMarketId, -(self.collateralAmounts[synthMarketId].toInt()) ); + } else { + _deductAllSynth(self, factory, synthMarketId); } } } @@ -306,7 +305,8 @@ library PerpsAccount { type(uint).max, address(0) ); - // TODO: deposit snxUSD + + factory.depositMarketUsd(leftoverAmount); updateCollateralAmount(self, marketId, -(amountToDeduct.toInt())); leftoverAmount = 0; @@ -324,7 +324,8 @@ library PerpsAccount { 0, address(0) ); - // TODO: deposit snxUSD + + factory.depositMarketUsd(amountToDeductUsd); updateCollateralAmount(self, marketId, -(availableAmount.toInt())); leftoverAmount -= amountToDeductUsd; @@ -337,70 +338,52 @@ library PerpsAccount { } } - function liquidateAccount(Data storage self) internal returns (uint256 reward) { - SetUtil.UintSet storage openPositionMarketIds = self.openPositionMarketIds; - uint256 openPositionsLength = openPositionMarketIds.length(); - - uint accumulatedLiquidationRewards; - - for (uint i = 1; i <= openPositionsLength; i++) { - uint128 positionMarketId = openPositionMarketIds.valueAt(i).to128(); - PerpsMarket.Data storage perpsMarket = PerpsMarket.load(positionMarketId); - Position.Data storage position = perpsMarket.positions[self.id]; - - (, , uint liquidationReward, ) = _liquidatePosition(self, positionMarketId, position); - accumulatedLiquidationRewards += liquidationReward; - } - - reward = _processLiquidationRewards(accumulatedLiquidationRewards); - } - - function _processLiquidationRewards(uint256 totalRewards) private returns (uint256 reward) { - // pay out liquidation rewards - reward = GlobalPerpsMarketConfiguration.load().liquidationReward(totalRewards); - if (reward > 0) { - PerpsMarketFactory.Data storage factory = PerpsMarketFactory.load(); - factory.synthetix.withdrawMarketUsd(factory.perpsMarketId, msg.sender, reward); - } - } - - function _liquidatePosition( + function liquidatePosition( Data storage self, uint128 marketId, - Position.Data storage position + uint256 price ) - private + internal returns ( uint128 amountToLiquidate, - int totalPnl, - uint liquidationReward, - int128 oldPositionSize + int128 newPositionSize, + int128 sizeDelta, + PerpsMarket.MarketUpdateData memory marketUpdateData ) { PerpsMarket.Data storage perpsMarket = PerpsMarket.load(marketId); + Position.Data storage position = perpsMarket.positions[self.id]; - oldPositionSize = position.size; - amountToLiquidate = perpsMarket.maxLiquidatableAmount(MathUtil.abs(oldPositionSize)); - uint price = PerpsPrice.getCurrentPrice(marketId); + perpsMarket.recomputeFunding(price); - (, totalPnl, , , ) = position.getPositionData(price); + int128 oldPositionSize = position.size; + amountToLiquidate = perpsMarket.maxLiquidatableAmount(MathUtil.abs(oldPositionSize)); int128 amtToLiquidationInt = amountToLiquidate.toInt(); // reduce position size - position.size = oldPositionSize > 0 + newPositionSize = oldPositionSize > 0 ? oldPositionSize - amtToLiquidationInt : oldPositionSize + amtToLiquidationInt; + // create new position in case of partial liquidation + Position.Data memory newPosition; + if (newPositionSize != 0) { + newPosition = Position.Data({ + marketId: marketId, + latestInteractionPrice: price.to128(), + latestInteractionFunding: perpsMarket.lastFundingValue.to128(), + size: newPositionSize + }); + } + // update position markets - updateOpenPositions(self, marketId, position.size); + updateOpenPositions(self, marketId, newPositionSize); // update market data - perpsMarket.updateMarketSizes(oldPositionSize, position.size); + marketUpdateData = perpsMarket.updatePositionData(self.id, newPosition); + sizeDelta = position.size - oldPositionSize; - // using amountToLiquidate to calculate liquidation reward - (, , , , liquidationReward) = PerpsMarketConfiguration - .load(marketId) - .calculateRequiredMargins(amtToLiquidationInt, price); + return (amountToLiquidate, position.size, sizeDelta, marketUpdateData); } function _deductAllSynth( @@ -423,7 +406,7 @@ library PerpsAccount { ); // 3. deposit snxUSD into market manager - factory.synthetix.depositMarketUsd(factory.perpsMarketId, address(this), amountUsd); + factory.depositMarketUsd(amountUsd); // 4. update account collateral amount updateCollateralAmount(self, synthMarketId, -(amount.toInt())); diff --git a/markets/perps-market/contracts/storage/PerpsMarket.sol b/markets/perps-market/contracts/storage/PerpsMarket.sol index b759e25492..5efebe9ed4 100644 --- a/markets/perps-market/contracts/storage/PerpsMarket.sol +++ b/markets/perps-market/contracts/storage/PerpsMarket.sol @@ -98,6 +98,12 @@ library PerpsMarket { PerpsMarketConfiguration.Data storage marketConfig = PerpsMarketConfiguration.load(self.id); uint maxLiquidationAmountPerSecond = marketConfig.maxLiquidationAmountPerSecond(); + // this would only be 0 if fees or skew scale are configured to be 0. + // in that case, (very unlikely), allow full liquidation + if (maxLiquidationAmountPerSecond == 0) { + return requestedLiquidationAmount.to128(); + } + uint timeSinceLastUpdate = block.timestamp - self.lastTimeLiquidationCapacityUpdated; uint maxSecondsInLiquidationWindow = marketConfig.maxSecondsInLiquidationWindow; @@ -142,10 +148,13 @@ library PerpsMarket { ) internal returns (MarketUpdateData memory) { Position.Data storage oldPosition = self.positions[accountId]; int128 oldPositionSize = oldPosition.size; + int128 newPositionSize = newPosition.size; + + self.size = (self.size + MathUtil.abs(newPositionSize)) - MathUtil.abs(oldPositionSize); + self.skew += newPositionSize - oldPositionSize; + + oldPosition.update(newPosition); - updateMarketSizes(self, newPosition.size, oldPositionSize); - oldPosition.updatePosition(newPosition); - // TODO add current market debt return MarketUpdateData( self.id, @@ -156,15 +165,6 @@ library PerpsMarket { ); } - function updateMarketSizes( - Data storage self, - int128 newPositionSize, - int128 oldPositionSize - ) internal { - self.size = (self.size + MathUtil.abs(newPositionSize)) - MathUtil.abs(oldPositionSize); - self.skew += newPositionSize - oldPositionSize; - } - function recomputeFunding( Data storage self, uint price diff --git a/markets/perps-market/contracts/storage/PerpsMarketFactory.sol b/markets/perps-market/contracts/storage/PerpsMarketFactory.sol index 3979a1c6a6..39be6c45f6 100644 --- a/markets/perps-market/contracts/storage/PerpsMarketFactory.sol +++ b/markets/perps-market/contracts/storage/PerpsMarketFactory.sol @@ -62,8 +62,12 @@ library PerpsMarketFactory { self.synthetix.depositMarketCollateral(self.perpsMarketId, address(collateral), amount); } - function depositToMarketManager(Data storage self, uint128 marketId, uint256 amount) internal { + function depositMarketUsd(Data storage self, uint256 amount) internal { self.usdToken.approve(address(this), amount); - self.synthetix.depositMarketUsd(marketId, address(this), amount); + self.synthetix.depositMarketUsd(self.perpsMarketId, address(this), amount); + } + + function withdrawMarketUsd(Data storage self, address to, uint256 amount) internal { + self.synthetix.withdrawMarketUsd(self.perpsMarketId, to, amount); } } diff --git a/markets/perps-market/contracts/storage/Position.sol b/markets/perps-market/contracts/storage/Position.sol index 3e2ef0b688..b333102473 100644 --- a/markets/perps-market/contracts/storage/Position.sol +++ b/markets/perps-market/contracts/storage/Position.sol @@ -26,7 +26,7 @@ library Position { int128 latestInteractionFunding; } - function updatePosition(Data storage self, Data memory newPosition) internal { + function update(Data storage self, Data memory newPosition) internal { self.size = newPosition.size; self.marketId = newPosition.marketId; self.latestInteractionPrice = newPosition.latestInteractionPrice; diff --git a/markets/perps-market/test/integration/Liquidation/Liquidation.margin.test.ts b/markets/perps-market/test/integration/Liquidation/Liquidation.margin.test.ts index fefa5c2fef..0986878bdc 100644 --- a/markets/perps-market/test/integration/Liquidation/Liquidation.margin.test.ts +++ b/markets/perps-market/test/integration/Liquidation/Liquidation.margin.test.ts @@ -98,7 +98,7 @@ describe('Liquidation - margin', async () => { }, ]; - const { systems, provider, trader1, perpsMarkets, owner } = bootstrapMarkets({ + const { systems, provider, trader1, perpsMarkets, owner, keeper } = bootstrapMarkets({ synthMarkets: [], perpsMarkets: perpsMarketConfigs, traderAccountIds: [2, 3], @@ -184,6 +184,13 @@ describe('Liquidation - margin', async () => { it('has correct available margin', async () => { assertBn.equal(await systems().PerpsMarket.getAvailableMargin(2), bn(18_850)); }); + + it('is not eligible for liquidation', async () => { + await assertRevert( + systems().PerpsMarket.connect(keeper()).liquidate(2), + 'NotEligibleForLiquidation' + ); + }); }); describe('prices changes', () => { @@ -218,6 +225,13 @@ describe('Liquidation - margin', async () => { it('has correct available margin', async () => { assertBn.equal(await systems().PerpsMarket.getAvailableMargin(2), bn(16_550)); }); + + it('is not eligible for liquidation', async () => { + await assertRevert( + systems().PerpsMarket.connect(keeper()).liquidate(2), + 'NotEligibleForLiquidation' + ); + }); }); describe('price change - available margin 0 ', () => { [ diff --git a/markets/perps-market/test/integration/Liquidation/Liquidation.multi-collateral.test.ts b/markets/perps-market/test/integration/Liquidation/Liquidation.multi-collateral.test.ts new file mode 100644 index 0000000000..9dd507b032 --- /dev/null +++ b/markets/perps-market/test/integration/Liquidation/Liquidation.multi-collateral.test.ts @@ -0,0 +1,292 @@ +import assertBn from '@synthetixio/core-utils/utils/assertions/assert-bignumber'; +import { bn, bootstrapMarkets } from '../bootstrap'; +import { OpenPositionData, depositCollateral, openPosition } from '../helpers'; +import { SynthMarkets } from '@synthetixio/spot-market/test/common'; +import assertEvent from '@synthetixio/core-utils/utils/assertions/assert-event'; +import { ethers } from 'ethers'; +import { calculatePricePnl } from '../helpers/fillPrice'; +import { wei } from '@synthetixio/wei'; + +describe('Liquidation - multi collateral', async () => { + const perpsMarketConfigs = [ + { + requestedMarketId: 50, + name: 'Bitcoin', + token: 'BTC', + price: bn(30_000), + fundingParams: { skewScale: bn(100), maxFundingVelocity: bn(0) }, + liquidationParams: { + initialMarginFraction: bn(2), + maintenanceMarginFraction: bn(1), + maxLiquidationLimitAccumulationMultiplier: bn(1), + liquidationRewardRatio: bn(0.01), + maxSecondsInLiquidationWindow: bn(10), + minimumPositionMargin: bn(0), + }, + settlementStrategy: { + settlementReward: bn(0), + }, + }, + { + requestedMarketId: 51, + name: 'Ether', + token: 'ETH', + price: bn(2000), + fundingParams: { skewScale: bn(1000), maxFundingVelocity: bn(0) }, + liquidationParams: { + initialMarginFraction: bn(2), + maintenanceMarginFraction: bn(1), + maxLiquidationLimitAccumulationMultiplier: bn(1), + liquidationRewardRatio: bn(0.02), + maxSecondsInLiquidationWindow: bn(10), + minimumPositionMargin: bn(0), + }, + settlementStrategy: { + settlementReward: bn(0), + }, + }, + { + requestedMarketId: 52, + name: 'Link', + token: 'LINK', + price: bn(5), + fundingParams: { skewScale: bn(100_000), maxFundingVelocity: bn(0) }, + liquidationParams: { + initialMarginFraction: bn(2), + maintenanceMarginFraction: bn(1), + maxLiquidationLimitAccumulationMultiplier: bn(1), + liquidationRewardRatio: bn(0.05), + maxSecondsInLiquidationWindow: bn(10), + minimumPositionMargin: bn(0), + }, + settlementStrategy: { + settlementReward: bn(0), + }, + }, + ]; + + const { systems, provider, trader1, synthMarkets, keeper, superMarketId, perpsMarkets } = + bootstrapMarkets({ + liquidationGuards: { + minLiquidationReward: bn(10), + maxLiquidationReward: bn(1000), + }, + synthMarkets: [ + { + name: 'Bitcoin', + token: 'snxBTC', + buyPrice: bn(30_000), + sellPrice: bn(30_000), + }, + { + name: 'Ethereum', + token: 'snxETH', + buyPrice: bn(2000), + sellPrice: bn(2000), + }, + ], + perpsMarkets: perpsMarketConfigs, + traderAccountIds: [2, 3], + }); + + let btcSynth: SynthMarkets[number], + ethSynth: SynthMarkets[number], + startingWithdrawableUsd: ethers.BigNumber; + + before('identify actors', async () => { + btcSynth = synthMarkets()[0]; + ethSynth = synthMarkets()[1]; + startingWithdrawableUsd = await systems().Core.getWithdrawableMarketUsd(superMarketId()); + }); + + before('add collateral to margin', async () => { + await depositCollateral({ + systems, + trader: trader1, + accountId: () => 2, + collaterals: [ + { + synthMarket: () => btcSynth, + snxUSDAmount: () => bn(10_000), + }, + { + synthMarket: () => ethSynth, + snxUSDAmount: () => bn(4000), + }, + ], + }); + }); + + // sanity check + it('has correct total collateral value', async () => { + assertBn.near( + await systems().PerpsMarket.totalCollateralValue(2), + bn(10_000 + 4000), + bn(0.00001) + ); + }); + + let commonOpenPositionProps: Pick< + OpenPositionData, + 'systems' | 'provider' | 'trader' | 'accountId' | 'keeper' + >; + before('identify common props', async () => { + commonOpenPositionProps = { + systems, + provider, + trader: trader1(), + accountId: 2, + keeper: trader1(), + }; + }); + + before('open positions', async () => { + const positionSizes = [ + bn(-1), // btc short + bn(20), // eth long + bn(2000), // link long + ]; + + for (const [i, perpsMarket] of perpsMarkets().entries()) { + await openPosition({ + ...commonOpenPositionProps, + marketId: perpsMarket.marketId(), + sizeDelta: positionSizes[i], + settlementStrategyId: perpsMarket.strategyId(), + price: perpsMarketConfigs[i].price, + }); + } + }); + + describe('account check after initial positions open', async () => { + it('should have correct open interest', async () => { + assertBn.equal(await systems().PerpsMarket.totalAccountOpenInterest(2), bn(80_000)); + }); + + [ + { size: bn(-1) }, // btc + { size: bn(20) }, // eth + { size: bn(2000) }, // link + ].forEach(({ size }, i) => { + it(`should have correct position for ${perpsMarketConfigs[i].token}`, async () => { + const [positionPnl, , positionSize] = await systems().PerpsMarket.getOpenPosition( + 2, + perpsMarkets()[i].marketId() + ); + const pnl = calculatePricePnl( + wei(0), + wei(perpsMarketConfigs[i].fundingParams.skewScale), + wei(size), + wei(perpsMarketConfigs[i].price) + ).toBN(); + assertBn.equal(positionPnl, pnl); + assertBn.equal(positionSize, size); + }); + }); + }); + + describe('make account liquidatable', () => { + before('change perps token price', async () => { + await perpsMarkets()[0].aggregator().mockSetCurrentPrice(bn(31000)); // btc + await perpsMarkets()[1].aggregator().mockSetCurrentPrice(bn(1625)); // eth + await perpsMarkets()[2].aggregator().mockSetCurrentPrice(bn(3)); // link + }); + + let liquidateTxn: ethers.providers.TransactionResponse; + before('liquidate account', async () => { + liquidateTxn = await systems().PerpsMarket.connect(keeper()).liquidate(2); + }); + + it('empties account margin', async () => { + assertBn.equal(await systems().PerpsMarket.totalCollateralValue(2), 0); + }); + + it('empties open interest', async () => { + assertBn.equal(await systems().PerpsMarket.totalAccountOpenInterest(2), 0); + }); + + it('emits account liquidated event', async () => { + await assertEvent( + liquidateTxn, + `AccountLiquidated(2, ${bn(1000)}, true)`, // max liquidation reward $1000 + systems().PerpsMarket + ); + }); + + it('sent reward to keeper', async () => { + assertBn.equal(await systems().USD.balanceOf(await keeper().getAddress()), bn(1000)); + }); + + [bn(1), bn(20), bn(2000)].forEach((liquidatedSize, i) => { + it(`emits position liquidated event`, async () => { + await assertEvent( + liquidateTxn, + `PositionLiquidated(2, ${perpsMarkets()[i].marketId()}, ${liquidatedSize}, 0)`, + systems().PerpsMarket + ); + }); + }); + + it('sold all market collateral for usd', async () => { + assertBn.equal( + await systems().Core.getMarketCollateralAmount(superMarketId(), btcSynth.synthAddress()), + bn(0) + ); + + assertBn.equal( + await systems().Core.getMarketCollateralAmount(superMarketId(), ethSynth.synthAddress()), + bn(0) + ); + }); + + // all collateral is still in the core system + it('has correct market usd', async () => { + // $14_000 total collateral value + // $1000 paid to liquidation reward + assertBn.near( + await systems().Core.getWithdrawableMarketUsd(superMarketId()), + startingWithdrawableUsd.add(bn(13_000)), + bn(0.00001) + ); + }); + }); + + // sanity check to ensure trader can add margin and open new positions after full account liquidation + describe('account can open new position', () => { + before('set btc price back to 30000', async () => { + await perpsMarkets()[0].aggregator().mockSetCurrentPrice(bn(30000)); + }); + + before('add margin', async () => { + await depositCollateral({ + systems, + trader: trader1, + accountId: () => 2, + collaterals: [ + { + synthMarket: () => ethSynth, + snxUSDAmount: () => bn(4000), + }, + ], + }); + }); + + before('open new position', async () => { + await openPosition({ + systems, + provider, + trader: trader1(), + accountId: 2, + keeper: trader1(), + marketId: perpsMarkets()[0].marketId(), + sizeDelta: bn(-1), + settlementStrategyId: perpsMarkets()[0].strategyId(), + price: perpsMarketConfigs[0].price, + }); + }); + + it('has correct open interest', async () => { + assertBn.equal(await systems().PerpsMarket.totalAccountOpenInterest(2), bn(30_000)); + }); + }); +}); diff --git a/markets/perps-market/test/integration/bootstrap/bootstrapPerpsMarkets.ts b/markets/perps-market/test/integration/bootstrap/bootstrapPerpsMarkets.ts index 48c79263ff..9f62ec96ee 100644 --- a/markets/perps-market/test/integration/bootstrap/bootstrapPerpsMarkets.ts +++ b/markets/perps-market/test/integration/bootstrap/bootstrapPerpsMarkets.ts @@ -15,7 +15,7 @@ export type PerpsMarket = { export type PerpsMarkets = Array; export type PerpsMarketData = Array<{ - requestedMarketId: ethers.BigNumber; + requestedMarketId: ethers.BigNumber | number; name: string; token: string; price: ethers.BigNumber; @@ -180,7 +180,7 @@ export const bootstrapPerpsMarkets = ( }); return { - marketId: () => marketId, + marketId: () => (isNumber(marketId) ? ethers.BigNumber.from(marketId) : marketId), aggregator: () => aggregator, strategyId: () => strategyId, }; @@ -198,3 +198,5 @@ export const bootstrapPerpsMarkets = ( poolId: r.poolId, }; }; + +const isNumber = (n: ethers.BigNumber | number): n is number => typeof n === 'number' && !isNaN(n); diff --git a/markets/perps-market/test/integration/helpers/fillPrice.ts b/markets/perps-market/test/integration/helpers/fillPrice.ts index c66a96dd3b..3befeefcb1 100644 --- a/markets/perps-market/test/integration/helpers/fillPrice.ts +++ b/markets/perps-market/test/integration/helpers/fillPrice.ts @@ -17,3 +17,13 @@ export function calculateFillPrice(skew: Wei, skewScale: Wei, size: Wei, price: return priceBefore.add(priceAfter).div(2); } + +export function calculatePricePnl( + startingSkew: Wei, + skewScale: Wei, + size: Wei, + startingPrice: Wei +) { + const fillPrice = calculateFillPrice(startingSkew, skewScale, size, startingPrice); + return startingPrice.sub(fillPrice).mul(size); +} From 08ea86daa550870ec07c47651394dbb0212eeca0 Mon Sep 17 00:00:00 2001 From: Sunny Vempati Date: Fri, 28 Jul 2023 13:30:25 -0500 Subject: [PATCH 17/63] add new views (#1731) * add new views * wip test * margin tests * more tests' * remove only * rename func * naming fix --- .../interfaces/IAsyncOrderModule.sol | 12 ++ ...ountModule.sol => IPerpsAccountModule.sol} | 25 ++- .../interfaces/IPerpsMarketModule.sol | 2 +- .../contracts/modules/AsyncOrderModule.sol | 28 ++- .../contracts/modules/LiquidationModule.sol | 2 +- .../contracts/modules/PerpsAccountModule.sol | 53 ++++-- .../contracts/modules/PerpsMarketModule.sol | 2 +- .../contracts/storage/AsyncOrder.sol | 10 +- .../contracts/storage/PerpsAccount.sol | 55 ++++-- .../storage/PerpsMarketConfiguration.sol | 8 +- .../test/integration/Account/Margins.test.ts | 164 ++++++++++++++++++ .../Account/ModifyCollateral.withdraw.test.ts | 26 ++- .../integration/Orders/GetOrderFees.test.ts | 0 .../Orders/OffchainAsyncOrder.fees.test.ts | 103 +++++------ .../test/integration/bootstrap/bootstrap.ts | 2 - .../test/integration/helpers/computeFees.ts | 49 ++++++ .../test/integration/helpers/index.ts | 2 + 17 files changed, 426 insertions(+), 117 deletions(-) rename markets/perps-market/contracts/interfaces/{IAccountModule.sol => IPerpsAccountModule.sol} (75%) create mode 100644 markets/perps-market/test/integration/Account/Margins.test.ts create mode 100644 markets/perps-market/test/integration/Orders/GetOrderFees.test.ts create mode 100644 markets/perps-market/test/integration/helpers/computeFees.ts diff --git a/markets/perps-market/contracts/interfaces/IAsyncOrderModule.sol b/markets/perps-market/contracts/interfaces/IAsyncOrderModule.sol index 2b7cbd7ff7..9d711041ff 100644 --- a/markets/perps-market/contracts/interfaces/IAsyncOrderModule.sol +++ b/markets/perps-market/contracts/interfaces/IAsyncOrderModule.sol @@ -74,4 +74,16 @@ interface IAsyncOrderModule { uint128 marketId, uint128 accountId ) external returns (AsyncOrder.Data memory order); + + /** + * @notice Simulates what the order fee would be for the given market with the specified size. + * @dev Note that this does not include the settlement reward fee, which is based on the strategy type used + * @param marketId id of the market. + * @param sizeDelta size of position. + * @return orderFees incurred fees. + */ + function computeOrderFees( + uint128 marketId, + int128 sizeDelta + ) external view returns (uint256 orderFees); } diff --git a/markets/perps-market/contracts/interfaces/IAccountModule.sol b/markets/perps-market/contracts/interfaces/IPerpsAccountModule.sol similarity index 75% rename from markets/perps-market/contracts/interfaces/IAccountModule.sol rename to markets/perps-market/contracts/interfaces/IPerpsAccountModule.sol index c34a6edc87..b49c5d0ee4 100644 --- a/markets/perps-market/contracts/interfaces/IAccountModule.sol +++ b/markets/perps-market/contracts/interfaces/IPerpsAccountModule.sol @@ -1,12 +1,10 @@ //SPDX-License-Identifier: MIT pragma solidity >=0.8.11 <0.9.0; -import {AsyncOrder} from "../storage/AsyncOrder.sol"; - /** * @title Account module */ -interface IAccountModule { +interface IPerpsAccountModule { /** * @notice Gets fired when an account colateral is modified. * @param accountId Id of the account. @@ -77,5 +75,24 @@ interface IAccountModule { * @param accountId Id of the account. * @return availableMargin available margin of the position. */ - function getAvailableMargin(uint128 accountId) external view returns (int); + function getAvailableMargin(uint128 accountId) external view returns (int256 availableMargin); + + /** + * @notice Gets the exact withdrawable amount a trader has available from this account while holding the account's current positions. + * @param accountId Id of the account. + * @return withdrawableMargin available margin to withdraw. + */ + function getWithdrawableMargin( + uint128 accountId + ) external view returns (int256 withdrawableMargin); + + /** + * @notice Gets the initial/maintenance margins across all positions that an account has open. + * @param accountId Id of the account. + * @return requiredInitialMargin initial margin req (used when withdrawing collateral). + * @return requiredMaintenanceMargin maintenance margin req (used to determine liquidation threshold). + */ + function getRequiredMargins( + uint128 accountId + ) external view returns (uint256 requiredInitialMargin, uint256 requiredMaintenanceMargin); } diff --git a/markets/perps-market/contracts/interfaces/IPerpsMarketModule.sol b/markets/perps-market/contracts/interfaces/IPerpsMarketModule.sol index e2d6e868e5..1041767681 100644 --- a/markets/perps-market/contracts/interfaces/IPerpsMarketModule.sol +++ b/markets/perps-market/contracts/interfaces/IPerpsMarketModule.sol @@ -32,7 +32,7 @@ interface IPerpsMarketModule { function indexPrice(uint128 marketId) external view returns (uint); - function fillPrice(uint128 marketId, int orderSize, uint price) external returns (uint); + function fillPrice(uint128 marketId, int128 orderSize, uint price) external returns (uint); /** * @dev Given a marketId return a market's summary details in one call. diff --git a/markets/perps-market/contracts/modules/AsyncOrderModule.sol b/markets/perps-market/contracts/modules/AsyncOrderModule.sol index 6941542fe7..ded39bcec4 100644 --- a/markets/perps-market/contracts/modules/AsyncOrderModule.sol +++ b/markets/perps-market/contracts/modules/AsyncOrderModule.sol @@ -6,7 +6,6 @@ import {DecimalMath} from "@synthetixio/core-contracts/contracts/utils/DecimalMa import {Account} from "@synthetixio/main/contracts/storage/Account.sol"; import {AccountRBAC} from "@synthetixio/main/contracts/storage/AccountRBAC.sol"; import {IPythVerifier} from "../interfaces/external/IPythVerifier.sol"; -import {IAccountModule} from "../interfaces/IAccountModule.sol"; import {IAsyncOrderModule} from "../interfaces/IAsyncOrderModule.sol"; import {PerpsAccount, SNX_USD_MARKET_ID} from "../storage/PerpsAccount.sol"; import {MathUtil} from "../utils/MathUtil.sol"; @@ -120,4 +119,31 @@ contract AsyncOrderModule is IAsyncOrderModule { emit OrderCanceled(marketId, accountId, order.settlementTime, order.acceptablePrice); } + + /** + * @inheritdoc IAsyncOrderModule + */ + function computeOrderFees( + uint128 marketId, + int128 sizeDelta + ) external view override returns (uint256 orderFees) { + PerpsMarket.Data storage perpsMarket = PerpsMarket.load(marketId); + int256 skew = perpsMarket.skew; + PerpsMarketConfiguration.Data storage marketConfig = PerpsMarketConfiguration.load( + marketId + ); + uint256 fillPrice = AsyncOrder.calculateFillPrice( + skew, + marketConfig.skewScale, + sizeDelta, + PerpsPrice.getCurrentPrice(marketId) + ); + + orderFees = AsyncOrder.calculateOrderFee( + sizeDelta, + fillPrice, + skew, + marketConfig.orderFees + ); + } } diff --git a/markets/perps-market/contracts/modules/LiquidationModule.sol b/markets/perps-market/contracts/modules/LiquidationModule.sol index ead4f1937f..0151737c65 100644 --- a/markets/perps-market/contracts/modules/LiquidationModule.sol +++ b/markets/perps-market/contracts/modules/LiquidationModule.sol @@ -30,7 +30,7 @@ contract LiquidationModule is ILiquidationModule, IMarketEvents { .liquidatableAccounts; PerpsAccount.Data storage account = PerpsAccount.load(accountId); if (!liquidatableAccounts.contains(accountId)) { - (bool isEligible, , ) = account.isEligibleForLiquidation(); + (bool isEligible, , , ) = account.isEligibleForLiquidation(); if (isEligible) { account.flagForLiquidation(); diff --git a/markets/perps-market/contracts/modules/PerpsAccountModule.sol b/markets/perps-market/contracts/modules/PerpsAccountModule.sol index 2845069aac..7a5d8f1f6a 100644 --- a/markets/perps-market/contracts/modules/PerpsAccountModule.sol +++ b/markets/perps-market/contracts/modules/PerpsAccountModule.sol @@ -5,7 +5,7 @@ import {Account} from "@synthetixio/main/contracts/storage/Account.sol"; import {AccountRBAC} from "@synthetixio/main/contracts/storage/AccountRBAC.sol"; import {ITokenModule} from "@synthetixio/core-modules/contracts/interfaces/ITokenModule.sol"; import {PerpsMarketFactory} from "../storage/PerpsMarketFactory.sol"; -import {IAccountModule} from "../interfaces/IAccountModule.sol"; +import {IPerpsAccountModule} from "../interfaces/IPerpsAccountModule.sol"; import {PerpsAccount} from "../storage/PerpsAccount.sol"; import {Position} from "../storage/Position.sol"; import {AsyncOrder} from "../storage/AsyncOrder.sol"; @@ -17,9 +17,9 @@ import {SafeCastU256, SafeCastI256} from "@synthetixio/core-contracts/contracts/ /** * @title Module to manage accounts - * @dev See IAccountModule. + * @dev See IPerpsAccountModule. */ -contract PerpsAccountModule is IAccountModule { +contract PerpsAccountModule is IPerpsAccountModule { using PerpsAccount for PerpsAccount.Data; using Position for Position.Data; using AsyncOrder for AsyncOrder.Data; @@ -29,7 +29,7 @@ contract PerpsAccountModule is IAccountModule { using PerpsMarketFactory for PerpsMarketFactory.Data; /** - * @inheritdoc IAccountModule + * @inheritdoc IPerpsAccountModule */ function modifyCollateral( uint128 accountId, @@ -71,21 +71,21 @@ contract PerpsAccountModule is IAccountModule { } /** - * @inheritdoc IAccountModule + * @inheritdoc IPerpsAccountModule */ function totalCollateralValue(uint128 accountId) external view override returns (uint) { return PerpsAccount.load(accountId).getTotalCollateralValue(); } /** - * @inheritdoc IAccountModule + * @inheritdoc IPerpsAccountModule */ function totalAccountOpenInterest(uint128 accountId) external view override returns (uint) { return PerpsAccount.load(accountId).getTotalNotionalOpenInterest(); } /** - * @inheritdoc IAccountModule + * @inheritdoc IPerpsAccountModule */ function getOpenPosition( uint128 accountId, @@ -102,14 +102,45 @@ contract PerpsAccountModule is IAccountModule { } /** - * @inheritdoc IAccountModule + * @inheritdoc IPerpsAccountModule */ - function getAvailableMargin(uint128 accountId) external view override returns (int) { - return PerpsAccount.load(accountId).getAvailableMargin(); + function getAvailableMargin( + uint128 accountId + ) external view override returns (int256 availableMargin) { + availableMargin = PerpsAccount.load(accountId).getAvailableMargin(); } /** - * @inheritdoc IAccountModule + * @inheritdoc IPerpsAccountModule + */ + function getWithdrawableMargin( + uint128 accountId + ) external view override returns (int256 withdrawableMargin) { + PerpsAccount.Data storage account = PerpsAccount.load(accountId); + int256 availableMargin = account.getAvailableMargin(); + (uint256 initialMaintenanceMargin, ) = account.getAccountRequiredMargins(); + + withdrawableMargin = availableMargin - initialMaintenanceMargin.toInt(); + } + + /** + * @inheritdoc IPerpsAccountModule + */ + function getRequiredMargins( + uint128 accountId + ) + external + view + override + returns (uint256 requiredInitialMargin, uint256 requiredMaintenanceMargin) + { + (requiredInitialMargin, requiredMaintenanceMargin) = PerpsAccount + .load(accountId) + .getAccountRequiredMargins(); + } + + /** + * @inheritdoc IPerpsAccountModule */ function getCollateralAmount( uint128 accountId, diff --git a/markets/perps-market/contracts/modules/PerpsMarketModule.sol b/markets/perps-market/contracts/modules/PerpsMarketModule.sol index 60e43117d1..5755766c8f 100644 --- a/markets/perps-market/contracts/modules/PerpsMarketModule.sol +++ b/markets/perps-market/contracts/modules/PerpsMarketModule.sol @@ -45,7 +45,7 @@ contract PerpsMarketModule is IPerpsMarketModule { function fillPrice( uint128 marketId, - int orderSize, + int128 orderSize, uint price ) external view override returns (uint) { return diff --git a/markets/perps-market/contracts/storage/AsyncOrder.sol b/markets/perps-market/contracts/storage/AsyncOrder.sol index 30b8188ce0..58f8adabe2 100644 --- a/markets/perps-market/contracts/storage/AsyncOrder.sol +++ b/markets/perps-market/contracts/storage/AsyncOrder.sol @@ -295,7 +295,7 @@ library AsyncOrder { PerpsAccount.Data storage account = PerpsAccount.load(order.accountId); bool isEligible; - (isEligible, runtime.currentAvailableMargin, runtime.requiredMaintenanceMargin) = account + (isEligible, runtime.currentAvailableMargin, , runtime.requiredMaintenanceMargin) = account .isEligibleForLiquidation(); if (isEligible) { @@ -431,10 +431,10 @@ library AsyncOrder { * @notice Calculates the fill price for an order. */ function calculateFillPrice( - int skew, - uint skewScale, - int size, - uint price + int256 skew, + uint256 skewScale, + int128 size, + uint256 price ) internal pure returns (uint) { // How is the p/d-adjusted price calculated using an example: // diff --git a/markets/perps-market/contracts/storage/PerpsAccount.sol b/markets/perps-market/contracts/storage/PerpsAccount.sol index 5695e18701..5fe986cd90 100644 --- a/markets/perps-market/contracts/storage/PerpsAccount.sol +++ b/markets/perps-market/contracts/storage/PerpsAccount.sol @@ -75,13 +75,18 @@ library PerpsAccount { ) internal view - returns (bool isEligible, int256 availableMargin, uint256 requiredMaintenanceMargin) + returns ( + bool isEligible, + int256 availableMargin, + uint256 requiredInitialMargin, + uint256 requiredMaintenanceMargin + ) { availableMargin = getAvailableMargin(self); if (self.openPositionMarketIds.length() == 0) { - return (false, availableMargin, 0); + return (false, availableMargin, 0, 0); } - requiredMaintenanceMargin = getAccountMaintenanceMargin(self); + (requiredInitialMargin, requiredMaintenanceMargin) = getAccountRequiredMargins(self); isEligible = requiredMaintenanceMargin.toInt() > availableMargin; } @@ -133,7 +138,7 @@ library PerpsAccount { /** * @notice This function validates you have enough margin to withdraw without being liquidated. - * @dev This is done by checking your collateral value against your margin maintenance value. + * @dev This is done by checking your collateral value against your initial maintenance value. */ function validateWithdrawableAmount( Data storage self, @@ -142,7 +147,8 @@ library PerpsAccount { ( bool isEligible, int256 availableMargin, - uint256 requiredMaintenanceMargin + uint256 initialMaintenanceMargin, + ) = isEligibleForLiquidation(self); if (isEligible) { @@ -150,7 +156,7 @@ library PerpsAccount { } // availableMargin can be assumed to be positive since we check for isEligible for liquidation prior - availableWithdrawableCollateralUsd = availableMargin.toUint() - requiredMaintenanceMargin; + availableWithdrawableCollateralUsd = availableMargin.toUint() - initialMaintenanceMargin; if (amountToWithdraw > availableWithdrawableCollateralUsd) { revert InsufficientCollateralAvailableForWithdraw( @@ -209,11 +215,13 @@ library PerpsAccount { } /** - * @notice This function returns the minimum margin an account requires to stay above liquidation threshold + * @notice This function returns the required margins for an account + * @dev The initial required margin is used to determine withdrawal amount and when opening positions + * @dev The maintenance margin is used to determine when to liquidate a position */ - function getAccountMaintenanceMargin( + function getAccountRequiredMargins( Data storage self - ) internal view returns (uint accountMaintenanceMargin) { + ) internal view returns (uint initialMargin, uint maintenanceMargin) { // use separate accounting for liquidation rewards so we can compare against global min/max liquidation reward values uint256 accumulatedLiquidationRewards; for (uint i = 1; i <= self.openPositionMarketIds.length(); i++) { @@ -222,18 +230,31 @@ library PerpsAccount { PerpsMarketConfiguration.Data storage marketConfig = PerpsMarketConfiguration.load( marketId ); - (, , , uint256 positionMaintenanceMargin, uint256 liquidationMargin) = marketConfig - .calculateRequiredMargins(position.size, PerpsPrice.getCurrentPrice(marketId)); + ( + , + , + uint256 positionInitialMargin, + uint256 positionMaintenanceMargin, + uint256 liquidationMargin + ) = marketConfig.calculateRequiredMargins( + position.size, + PerpsPrice.getCurrentPrice(marketId) + ); accumulatedLiquidationRewards += liquidationMargin; - accountMaintenanceMargin += - positionMaintenanceMargin + - marketConfig.minimumPositionMargin; + maintenanceMargin += positionMaintenanceMargin; + initialMargin += positionInitialMargin; } - return - accountMaintenanceMargin + - GlobalPerpsMarketConfiguration.load().liquidationReward(accumulatedLiquidationRewards); + // if account was liquidated, we account for liquidation reward that would be paid out to the liquidation keeper in required margin + uint256 possibleLiquidationReward = GlobalPerpsMarketConfiguration.load().liquidationReward( + accumulatedLiquidationRewards + ); + + return ( + initialMargin + possibleLiquidationReward, + maintenanceMargin + possibleLiquidationReward + ); } function convertAllCollateralToUsd(Data storage self) internal { diff --git a/markets/perps-market/contracts/storage/PerpsMarketConfiguration.sol b/markets/perps-market/contracts/storage/PerpsMarketConfiguration.sol index 35e8a6f74f..29b75c4d35 100644 --- a/markets/perps-market/contracts/storage/PerpsMarketConfiguration.sol +++ b/markets/perps-market/contracts/storage/PerpsMarketConfiguration.sol @@ -48,7 +48,7 @@ library PerpsMarketConfiguration { */ uint256 liquidationRewardRatioD18; /** - * @dev minimum position value in USD, this is used when we calculate maintenance margin + * @dev minimum position value in USD, this is a constant value added to position margin requirements (initial/maintenance) */ uint256 minimumPositionMargin; } @@ -99,8 +99,10 @@ library PerpsMarketConfiguration { maintenanceMarginRatio = impactOnSkew.mulDecimal(self.maintenanceMarginRatioD18); uint256 notional = sizeAbs.mulDecimal(price); - initialMargin = notional.mulDecimal(initialMarginRatio); - maintenanceMargin = notional.mulDecimal(maintenanceMarginRatio); + initialMargin = notional.mulDecimal(initialMarginRatio) + self.minimumPositionMargin; + maintenanceMargin = + notional.mulDecimal(maintenanceMarginRatio) + + self.minimumPositionMargin; liquidationMargin = calculateLiquidationReward(self, notional); } diff --git a/markets/perps-market/test/integration/Account/Margins.test.ts b/markets/perps-market/test/integration/Account/Margins.test.ts new file mode 100644 index 0000000000..9a1f1ef6fb --- /dev/null +++ b/markets/perps-market/test/integration/Account/Margins.test.ts @@ -0,0 +1,164 @@ +import { bn, bootstrapMarkets } from '../bootstrap'; +import assertBn from '@synthetixio/core-utils/src/utils/assertions/assert-bignumber'; +import { openPosition } from '../helpers'; +import Wei, { wei } from '@synthetixio/wei'; +import { calculatePricePnl } from '../helpers/fillPrice'; + +describe('Account margins test', () => { + const accountId = 4; + const perpsMarketConfig = [ + { + requestedMarketId: 25, + name: 'Bitcoin', + token: 'BTC', + price: bn(30_000), + fundingParams: { skewScale: bn(100), maxFundingVelocity: bn(0) }, + liquidationParams: { + initialMarginFraction: bn(2), + maintenanceMarginFraction: bn(1), + maxLiquidationLimitAccumulationMultiplier: bn(1), + liquidationRewardRatio: bn(0.05), + maxSecondsInLiquidationWindow: bn(10), + minimumPositionMargin: bn(1000), + }, + settlementStrategy: { + settlementReward: bn(0), + }, + }, + { + requestedMarketId: 26, + name: 'Ether', + token: 'ETH', + price: bn(2000), + fundingParams: { skewScale: bn(1000), maxFundingVelocity: bn(0) }, + liquidationParams: { + initialMarginFraction: bn(2), + maintenanceMarginFraction: bn(1), + maxLiquidationLimitAccumulationMultiplier: bn(1), + liquidationRewardRatio: bn(0.05), + maxSecondsInLiquidationWindow: bn(10), + minimumPositionMargin: bn(500), + }, + settlementStrategy: { + settlementReward: bn(0), + }, + }, + ]; + const { systems, provider, trader1, perpsMarkets } = bootstrapMarkets({ + synthMarkets: [], + perpsMarkets: perpsMarketConfig, + traderAccountIds: [accountId, 5], + }); + + // add $100k + before('add some snx collateral to margin', async () => { + await systems().PerpsMarket.connect(trader1()).modifyCollateral(accountId, 0, bn(100_000)); + }); + + describe('before open positions', () => { + it('has correct available margin', async () => { + assertBn.equal(await systems().PerpsMarket.getAvailableMargin(accountId), bn(100_000)); + }); + + it('has correct withdrawable margin', async () => { + assertBn.equal(await systems().PerpsMarket.getWithdrawableMargin(accountId), bn(100_000)); + }); + + it('has correct initial and maintenance margin', async () => { + const [initialMargin, maintenanceMargin] = await systems().PerpsMarket.getRequiredMargins( + accountId + ); + assertBn.equal(initialMargin, 0); + assertBn.equal(maintenanceMargin, 0); + }); + }); + + describe('after open positions', () => { + before('open 2 positions', async () => { + await openPosition({ + systems, + provider, + trader: trader1(), + accountId, + keeper: trader1(), + marketId: perpsMarkets()[0].marketId(), + sizeDelta: bn(-2), + settlementStrategyId: perpsMarkets()[0].strategyId(), + price: bn(30_000), + }); + await openPosition({ + systems, + provider, + trader: trader1(), + accountId, + keeper: trader1(), + marketId: perpsMarkets()[1].marketId(), + sizeDelta: bn(20), + settlementStrategyId: perpsMarkets()[1].strategyId(), + price: bn(2_000), + }); + }); + + let startingMargin: Wei, + initialPnl: Wei, + btcInitialMargin: Wei, + ethInitialMargin: Wei, + btcMaintenanceMargin: Wei, + ethMaintenanceMargin: Wei, + minimumPositionMargin: Wei; + before('identify expected values', () => { + startingMargin = wei(100_000); + const btcSkewScale = wei(perpsMarketConfig[0].fundingParams.skewScale); + const ethSkewScale = wei(perpsMarketConfig[1].fundingParams.skewScale); + const btcPnl = calculatePricePnl(wei(0), btcSkewScale, wei(-2), wei(30_000)); + const ethPnl = calculatePricePnl(wei(0), ethSkewScale, wei(20), wei(2000)); + initialPnl = btcPnl.add(ethPnl); + + const notionalBtcValue = wei(2).mul(wei(30_000)); + const notionalEthValue = wei(20).mul(wei(2000)); + + btcInitialMargin = notionalBtcValue.mul(wei(2).div(wei(btcSkewScale)).mul(wei(2))); + ethInitialMargin = notionalEthValue.mul(wei(20).div(wei(ethSkewScale)).mul(wei(2))); + + // maintenance margin ratio == 1 + btcMaintenanceMargin = notionalBtcValue.mul(wei(2).div(wei(btcSkewScale))); + ethMaintenanceMargin = notionalEthValue.mul(wei(20).div(wei(ethSkewScale))); + + // in above config: 1000 + 500 + minimumPositionMargin = wei(1500); + }); + + it('has correct available margin', async () => { + assertBn.equal( + await systems().PerpsMarket.getAvailableMargin(accountId), + startingMargin.add(initialPnl).toBN() + ); + }); + + it('has correct withdrawable margin', async () => { + assertBn.equal( + await systems().PerpsMarket.getWithdrawableMargin(accountId), + startingMargin + .add(initialPnl) + .sub(btcInitialMargin) + .sub(ethInitialMargin) + .sub(minimumPositionMargin) + .toBN() + ); + }); + + it('has correct initial and maintenance margin', async () => { + const [initialMargin, maintenanceMargin] = await systems().PerpsMarket.getRequiredMargins( + accountId + ); + assertBn.equal( + initialMargin, + btcInitialMargin.add(ethInitialMargin).add(minimumPositionMargin).toBN() + ); + assertBn.equal( + maintenanceMargin, + btcMaintenanceMargin.add(ethMaintenanceMargin).add(minimumPositionMargin).toBN() + ); + }); + }); +}); diff --git a/markets/perps-market/test/integration/Account/ModifyCollateral.withdraw.test.ts b/markets/perps-market/test/integration/Account/ModifyCollateral.withdraw.test.ts index 81a2a97999..673edd7333 100644 --- a/markets/perps-market/test/integration/Account/ModifyCollateral.withdraw.test.ts +++ b/markets/perps-market/test/integration/Account/ModifyCollateral.withdraw.test.ts @@ -93,22 +93,12 @@ describe('ModifyCollateral Withdraw', () => { }); it('properly reflects core system collateral balance', async () => { - // const perpsBalanceAfter = await synthMarkets()[0] - // .synth() - // .connect(trader1()) - // .balanceOf(systems().PerpsMarket.address); - const btcCollateralValue = await systems().Core.getMarketCollateralAmount( superMarketId(), synthMarkets()[0].synthAddress() ); assertBn.equal(btcCollateralValue, depositAmount.sub(withdrawAmount).toBN()); - - // assertBn.equal( - // perpsBalanceAfter, - // wei(perpsBalanceBefore).add(depositAmount).sub(withdrawAmount).toBN() - // ); }); it('emits correct event with the expected values', async () => { @@ -259,20 +249,28 @@ describe('ModifyCollateral Withdraw', () => { ); }); }); - describe('allow withdraw when its less than "collateral available for withdraw', () => { + describe('allow withdraw when its less than collateral available for withdraw', () => { const restore = snapshotCheckpoint(provider); + let initialMarginReq: ethers.BigNumber; + before('withdraw allowed amount', async () => { + [initialMarginReq] = await systems() + .PerpsMarket.connect(trader1()) + .getRequiredMargins(trader1AccountId); + // available margin = collateral value + pnl = $19000 + const withdrawAmt = bn(19_000).sub(initialMarginReq).mul(-1); + await systems() .PerpsMarket.connect(trader1()) - .modifyCollateral(trader1AccountId, sUSDSynthId, bn(-17000)); + .modifyCollateral(trader1AccountId, sUSDSynthId, withdrawAmt); }); after(restore); it('has correct available margin', async () => { assertBn.equal( await systems().PerpsMarket.getAvailableMargin(trader1AccountId), - bn(2000) // collateral value + pnl = (20000 - 17000) + -1000 + initialMarginReq ); }); }); @@ -292,7 +290,7 @@ describe('ModifyCollateral Withdraw', () => { systems() .PerpsMarket.connect(trader1()) .modifyCollateral(trader1AccountId, sUSDSynthId, bn(-18000)), - `InsufficientCollateralAvailableForWithdraw("${bn(17000)}", "${bn(18000)}")` + `InsufficientCollateralAvailableForWithdraw("${bn(15000)}", "${bn(18000)}")` ); }); diff --git a/markets/perps-market/test/integration/Orders/GetOrderFees.test.ts b/markets/perps-market/test/integration/Orders/GetOrderFees.test.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/markets/perps-market/test/integration/Orders/OffchainAsyncOrder.fees.test.ts b/markets/perps-market/test/integration/Orders/OffchainAsyncOrder.fees.test.ts index f23ed11bb3..97dc28a4fd 100644 --- a/markets/perps-market/test/integration/Orders/OffchainAsyncOrder.fees.test.ts +++ b/markets/perps-market/test/integration/Orders/OffchainAsyncOrder.fees.test.ts @@ -1,16 +1,24 @@ import { ethers } from 'ethers'; -import { DEFAULT_SETTLEMENT_STRATEGY, bn, bootstrapMarkets, decimalMul } from '../bootstrap'; +import { DEFAULT_SETTLEMENT_STRATEGY, bn, bootstrapMarkets } from '../bootstrap'; import { fastForwardTo } from '@synthetixio/core-utils/utils/hardhat/rpc'; import { snapshotCheckpoint } from '@synthetixio/core-utils/utils/mocha/snapshot'; import { SynthMarkets } from '@synthetixio/spot-market/test/common'; -import { OpenPositionData, depositCollateral, openPosition, settleOrder } from '../helpers'; +import { + Fees, + OpenPositionData, + computeFees, + depositCollateral, + openPosition, + settleOrder, +} from '../helpers'; import assertBn from '@synthetixio/core-utils/utils/assertions/assert-bignumber'; import { getTxTime } from '@synthetixio/core-utils/src/utils/hardhat/rpc'; +import Wei, { wei } from '@synthetixio/wei'; describe('Offchain Async Order test - fees', () => { const orderFees = { - makerFee: bn(0.0003), // 3bps - takerFee: bn(0.0008), // 8bps + makerFee: wei(0.0003), // 3bps + takerFee: wei(0.0008), // 8bps }; const ethPrice = bn(1000); @@ -31,7 +39,10 @@ describe('Offchain Async Order test - fees', () => { price: ethPrice, // setting to 0 to avoid funding and p/d price change affecting pnl fundingParams: { skewScale: bn(0), maxFundingVelocity: bn(0) }, - orderFees, + orderFees: { + makerFee: orderFees.makerFee.toBN(), + takerFee: orderFees.takerFee.toBN(), + }, }, ], traderAccountIds: [2, 3], @@ -115,12 +126,19 @@ describe('Offchain Async Order test - fees', () => { describe('single order - intermediate steps', () => { let tx: ethers.ContractTransaction; let startTime: number; - let feesPaidOnSettle: ReturnType; + let feesPaidOnSettle: Fees; before(restoreToSetOrder); + let fillPrice: Wei; + const sizeDelta = bn(1); + + before('get fill price', async () => { + fillPrice = wei(await systems().PerpsMarket.fillPrice(ethMarketId, sizeDelta, ethPrice)); + feesPaidOnSettle = computeFees(wei(0), wei(sizeDelta), fillPrice, orderFees); + }); + before('commit the order', async () => { - const sizeDelta = bn(1); tx = await systems() .PerpsMarket.connect(trader1()) .commitOrder({ @@ -133,10 +151,12 @@ describe('Offchain Async Order test - fees', () => { }); startTime = await getTxTime(provider(), tx); - feesPaidOnSettle = computeFees( - bn(0), - sizeDelta, - await systems().PerpsMarket.fillPrice(ethMarketId, sizeDelta, ethPrice) + }); + + it('returns proper fees on getOrderFees', async () => { + assertBn.equal( + await systems().PerpsMarket.computeOrderFees(ethMarketId, sizeDelta), + feesPaidOnSettle.perpsMarketFee ); }); @@ -205,7 +225,7 @@ describe('Offchain Async Order test - fees', () => { }); describe('multiple orders ', () => { - let feesPaidOnLong: ReturnType; + let feesPaidOnLong: Fees; let balancesAfterLong: { traderBalance: ethers.BigNumber; @@ -242,9 +262,10 @@ describe('Offchain Async Order test - fees', () => { before('open a long order (taker)', async () => { feesPaidOnLong = computeFees( - bn(0), - initialLongSize, - await systems().PerpsMarket.fillPrice(ethMarketId, initialLongSize, ethPrice) + wei(0), + wei(initialLongSize), + wei(await systems().PerpsMarket.fillPrice(ethMarketId, initialLongSize, ethPrice)), + orderFees ); await openPosition({ @@ -272,16 +293,17 @@ describe('Offchain Async Order test - fees', () => { const restoreToLongOrder = snapshotCheckpoint(provider); describe('reduce position size (maker)', () => { - let feesPaidOnShort: ReturnType; + let feesPaidOnShort: Fees; const sizeDelta = bn(-1); // original size is 2, reduce by 1 => still long, but smaller before(restoreToLongOrder); before('open a small short order', async () => { feesPaidOnShort = computeFees( - initialLongSize, - sizeDelta, - await systems().PerpsMarket.fillPrice(ethMarketId, sizeDelta, ethPrice) + wei(initialLongSize), + wei(sizeDelta), + wei(await systems().PerpsMarket.fillPrice(ethMarketId, sizeDelta, ethPrice)), + orderFees ); await openPosition({ @@ -308,16 +330,17 @@ describe('Offchain Async Order test - fees', () => { }); describe('flip the order side (maker + taker)', () => { - let feesPaidOnShort: ReturnType; + let feesPaidOnShort: Fees; const sizeDelta = bn(-3); // original size is 2, reduce by 3 => flip to short -1 before(restoreToLongOrder); before('open a large short order', async () => { feesPaidOnShort = computeFees( - initialLongSize, - sizeDelta, - await systems().PerpsMarket.fillPrice(ethMarketId, sizeDelta, ethPrice) + wei(initialLongSize), + wei(sizeDelta), + wei(await systems().PerpsMarket.fillPrice(ethMarketId, sizeDelta, ethPrice)), + orderFees ); await openPosition({ @@ -354,38 +377,4 @@ describe('Offchain Async Order test - fees', () => { accountPnl, }; }; - - const computeFees: ( - sizeBefore: ethers.BigNumber, - sizeDelta: ethers.BigNumber, - price: ethers.BigNumber - ) => { - totalFees: ethers.BigNumber; - keeperFee: ethers.BigNumber; - perpsMarketFee: ethers.BigNumber; - } = (sizeBefore, sizeDelta, price) => { - let makerSize = bn(0), - takerSize = bn(0); - - if (sizeDelta.isZero()) { - // no change in fees - } else if (sizeBefore.isZero() || sizeBefore.mul(sizeDelta).gt(0)) { - // same side. taker - takerSize = sizeDelta.abs(); - } else { - makerSize = sizeBefore.abs() > sizeDelta.abs() ? sizeDelta.abs() : sizeBefore.abs(); - takerSize = - sizeBefore.abs() < sizeDelta.abs() ? sizeDelta.abs().sub(sizeBefore.abs()) : bn(0); - } - - const notionalTaker = decimalMul(takerSize, price); - const notionalMaker = decimalMul(makerSize, price); - - const perpsMarketFee = decimalMul(notionalMaker, orderFees.makerFee).add( - decimalMul(notionalTaker, orderFees.takerFee) - ); - const keeperFee = DEFAULT_SETTLEMENT_STRATEGY.settlementReward; - - return { totalFees: perpsMarketFee.add(keeperFee), perpsMarketFee, keeperFee }; - }; }); diff --git a/markets/perps-market/test/integration/bootstrap/bootstrap.ts b/markets/perps-market/test/integration/bootstrap/bootstrap.ts index 12923365e0..c6d3cca9df 100644 --- a/markets/perps-market/test/integration/bootstrap/bootstrap.ts +++ b/markets/perps-market/test/integration/bootstrap/bootstrap.ts @@ -157,5 +157,3 @@ export function bootstrapMarkets(data: BootstrapArgs) { export const bn = (n: number) => wei(n).toBN(); export const toNum = (n: ethers.BigNumber) => Number(ethers.utils.formatEther(n)); -export const decimalMul = (a: ethers.BigNumber, b: ethers.BigNumber) => a.mul(b).div(bn(1)); -export const decimalDiv = (a: ethers.BigNumber, b: ethers.BigNumber) => a.mul(bn(1)).div(b); diff --git a/markets/perps-market/test/integration/helpers/computeFees.ts b/markets/perps-market/test/integration/helpers/computeFees.ts new file mode 100644 index 0000000000..49f2bba931 --- /dev/null +++ b/markets/perps-market/test/integration/helpers/computeFees.ts @@ -0,0 +1,49 @@ +import { ethers } from 'ethers'; +import { DEFAULT_SETTLEMENT_STRATEGY } from '../bootstrap'; +import Wei, { wei } from '@synthetixio/wei'; + +type OrderFees = { + makerFee: Wei; + takerFee: Wei; +}; + +export type Fees = { + totalFees: ethers.BigNumber; + keeperFee: ethers.BigNumber; + perpsMarketFee: ethers.BigNumber; +}; + +export const computeFees: ( + sizeBefore: Wei, + sizeDelta: Wei, + price: Wei, + orderFees: OrderFees +) => Fees = (sizeBefore, sizeDelta, price, orderFees) => { + let makerSize = wei(0), + takerSize = wei(0); + + if (sizeDelta.eq(0)) { + // no change in fees + } else if (sizeBefore.eq(0) || sizeBefore.mul(sizeDelta).gt(0)) { + // same side. taker + takerSize = sizeDelta.abs(); + } else { + makerSize = sizeBefore.abs() > sizeDelta.abs() ? sizeDelta.abs() : sizeBefore.abs(); + takerSize = sizeBefore.abs() < sizeDelta.abs() ? sizeDelta.abs().sub(sizeBefore.abs()) : wei(0); + } + + const notionalTaker = wei(takerSize).mul(wei(price)); + const notionalMaker = wei(makerSize).mul(price); + + const perpsMarketFee = notionalMaker + .mul(orderFees.makerFee) + .add(notionalTaker.mul(orderFees.takerFee)); + + const keeperFee = DEFAULT_SETTLEMENT_STRATEGY.settlementReward; + + return { + totalFees: perpsMarketFee.add(keeperFee).toBN(), + perpsMarketFee: perpsMarketFee.toBN(), + keeperFee, + }; +}; diff --git a/markets/perps-market/test/integration/helpers/index.ts b/markets/perps-market/test/integration/helpers/index.ts index b189f78c4f..6abdbe6026 100644 --- a/markets/perps-market/test/integration/helpers/index.ts +++ b/markets/perps-market/test/integration/helpers/index.ts @@ -1,3 +1,5 @@ export * from './settleHelper'; export * from './collateralHelper'; export * from './openPosition'; +export * from './fillPrice'; +export * from './computeFees'; From 3d5212803020d711bc09510b72d1654ce63f306c Mon Sep 17 00:00:00 2001 From: Leonardo Massazza Date: Mon, 31 Jul 2023 14:17:02 +0100 Subject: [PATCH 18/63] Market debt (#1700) * checkpoint - conceptual * template test * some comments * checkpoint: use requestedMarketId * linting * compute reported debt * doc fix (spotted) * market debt * checkpoint * wip: checkpoint * tests passing (and makes sense) * lint fix * rogue validation * Update markets/perps-market/contracts/modules/PerpsMarketFactoryModule.sol Co-authored-by: Sunny Vempati * wip test * wip test * test reported debt with funding and partial liquidations * remove console log * small cleanup * fix interface --------- Co-authored-by: Sunny Vempati --- .../interfaces/IGlobalPerpsMarketModule.sol | 6 + .../interfaces/IPerpsAccountModule.sol | 6 +- .../modules/AsyncOrderSettlementModule.sol | 2 +- .../modules/GlobalPerpsMarketModule.sol | 14 + .../contracts/modules/PerpsAccountModule.sol | 6 +- .../modules/PerpsMarketFactoryModule.sol | 31 +- .../contracts/storage/GlobalPerpsMarket.sol | 2 +- .../contracts/storage/PerpsAccount.sol | 4 +- .../contracts/storage/PerpsMarket.sol | 39 +- .../contracts/storage/Position.sol | 20 +- markets/perps-market/storage.dump.sol | 6 +- .../integration/Market/MarketDebt.test.ts | 341 ++++++++++++++++++ .../Market/MarketDebt.withFunding.test.ts | 298 +++++++++++++++ .../test/integration/bootstrap/bootstrap.ts | 3 +- .../integration/bootstrap/bootstrapTraders.ts | 23 +- .../contracts/interfaces/external/IMarket.sol | 2 +- protocol/synthetix/test/common/stakers.ts | 10 +- 17 files changed, 784 insertions(+), 29 deletions(-) create mode 100644 markets/perps-market/test/integration/Market/MarketDebt.test.ts create mode 100644 markets/perps-market/test/integration/Market/MarketDebt.withFunding.test.ts diff --git a/markets/perps-market/contracts/interfaces/IGlobalPerpsMarketModule.sol b/markets/perps-market/contracts/interfaces/IGlobalPerpsMarketModule.sol index fa95e0fa07..fb2f190d9d 100644 --- a/markets/perps-market/contracts/interfaces/IGlobalPerpsMarketModule.sol +++ b/markets/perps-market/contracts/interfaces/IGlobalPerpsMarketModule.sol @@ -75,4 +75,10 @@ interface IGlobalPerpsMarketModule { external view returns (uint256 minLiquidationRewardUsd, uint256 maxLiquidationRewardUsd); + + /** + * @notice Gets the total collateral value of all deposited collateral from all traders. + * @return totalCollateralValue value of all collateral + */ + function totalGlobalCollateralValue() external view returns (uint256 totalCollateralValue); } diff --git a/markets/perps-market/contracts/interfaces/IPerpsAccountModule.sol b/markets/perps-market/contracts/interfaces/IPerpsAccountModule.sol index b49c5d0ee4..e34f75bdbf 100644 --- a/markets/perps-market/contracts/interfaces/IPerpsAccountModule.sol +++ b/markets/perps-market/contracts/interfaces/IPerpsAccountModule.sol @@ -61,14 +61,14 @@ interface IPerpsAccountModule { * @notice Gets the details of an open position. * @param accountId Id of the account. * @param marketId Id of the position market. - * @return pnl pnl of the position. + * @return totalPnl pnl of the entire position including funding. * @return accruedFunding accrued funding of the position. - * @return size size of the position. + * @return positionSize size of the position. */ function getOpenPosition( uint128 accountId, uint128 marketId - ) external view returns (int pnl, int accruedFunding, int size); + ) external view returns (int256 totalPnl, int256 accruedFunding, int128 positionSize); /** * @notice Gets the available margin of an account. It can be negative due to pnl. diff --git a/markets/perps-market/contracts/modules/AsyncOrderSettlementModule.sol b/markets/perps-market/contracts/modules/AsyncOrderSettlementModule.sol index 2378eccbbe..c1216a73d9 100644 --- a/markets/perps-market/contracts/modules/AsyncOrderSettlementModule.sol +++ b/markets/perps-market/contracts/modules/AsyncOrderSettlementModule.sol @@ -140,7 +140,7 @@ contract AsyncOrderSettlementModule is IAsyncOrderSettlementModule, IMarketEvent PerpsAccount.Data storage perpsAccount = PerpsAccount.load(runtime.accountId); // use fill price to calculate realized pnl - (runtime.pnl, , , ) = oldPosition.getPnl(fillPrice); + (runtime.pnl, , , , ) = oldPosition.getPnl(fillPrice); runtime.pnlUint = MathUtil.abs(runtime.pnl); if (runtime.pnl > 0) { diff --git a/markets/perps-market/contracts/modules/GlobalPerpsMarketModule.sol b/markets/perps-market/contracts/modules/GlobalPerpsMarketModule.sol index 8f3ad29ac5..26528b9ae8 100644 --- a/markets/perps-market/contracts/modules/GlobalPerpsMarketModule.sol +++ b/markets/perps-market/contracts/modules/GlobalPerpsMarketModule.sol @@ -2,6 +2,7 @@ pragma solidity >=0.8.11 <0.9.0; import {GlobalPerpsMarketConfiguration} from "../storage/GlobalPerpsMarketConfiguration.sol"; +import {GlobalPerpsMarket} from "../storage/GlobalPerpsMarket.sol"; import {IGlobalPerpsMarketModule} from "../interfaces/IGlobalPerpsMarketModule.sol"; import {OwnableStorage} from "@synthetixio/core-contracts/contracts/ownership/OwnableStorage.sol"; @@ -11,6 +12,7 @@ import {OwnableStorage} from "@synthetixio/core-contracts/contracts/ownership/Ow */ contract GlobalPerpsMarketModule is IGlobalPerpsMarketModule { using GlobalPerpsMarketConfiguration for GlobalPerpsMarketConfiguration.Data; + using GlobalPerpsMarket for GlobalPerpsMarket.Data; /** * @inheritdoc IGlobalPerpsMarketModule @@ -81,4 +83,16 @@ contract GlobalPerpsMarketModule is IGlobalPerpsMarketModule { minLiquidationRewardUsd = store.minLiquidationRewardUsd; maxLiquidationRewardUsd = store.maxLiquidationRewardUsd; } + + /** + * @inheritdoc IGlobalPerpsMarketModule + */ + function totalGlobalCollateralValue() + external + view + override + returns (uint256 totalCollateralValue) + { + return GlobalPerpsMarket.load().totalCollateralValue(); + } } diff --git a/markets/perps-market/contracts/modules/PerpsAccountModule.sol b/markets/perps-market/contracts/modules/PerpsAccountModule.sol index 7a5d8f1f6a..01d08febf2 100644 --- a/markets/perps-market/contracts/modules/PerpsAccountModule.sol +++ b/markets/perps-market/contracts/modules/PerpsAccountModule.sol @@ -90,15 +90,15 @@ contract PerpsAccountModule is IPerpsAccountModule { function getOpenPosition( uint128 accountId, uint128 marketId - ) external view override returns (int, int, int) { + ) external view override returns (int256 totalPnl, int256 accruedFunding, int128 positionSize) { PerpsMarket.Data storage perpsMarket = PerpsMarket.loadValid(marketId); Position.Data storage position = perpsMarket.positions[accountId]; - (, int pnl, int accruedFunding, , ) = position.getPositionData( + (, totalPnl, , accruedFunding, , ) = position.getPositionData( PerpsPrice.getCurrentPrice(marketId) ); - return (pnl, accruedFunding, position.size); + return (totalPnl, accruedFunding, position.size); } /** diff --git a/markets/perps-market/contracts/modules/PerpsMarketFactoryModule.sol b/markets/perps-market/contracts/modules/PerpsMarketFactoryModule.sol index 5f622ebbb8..98dd4ebf72 100644 --- a/markets/perps-market/contracts/modules/PerpsMarketFactoryModule.sol +++ b/markets/perps-market/contracts/modules/PerpsMarketFactoryModule.sol @@ -23,6 +23,8 @@ import {ParameterError} from "@synthetixio/core-contracts/contracts/errors/Param import {MathUtil} from "../utils/MathUtil.sol"; import {PerpsMarketConfiguration} from "../storage/PerpsMarketConfiguration.sol"; import {IMarket} from "@synthetixio/main/contracts/interfaces/external/IMarket.sol"; +import {SetUtil} from "@synthetixio/core-contracts/contracts/utils/SetUtil.sol"; +import {SafeCastU256, SafeCastI256, SafeCastU128} from "@synthetixio/core-contracts/contracts/utils/SafeCast.sol"; /** * @title Module for registering perpetual futures markets. The factory tracks all markets in the system and consolidates implementation. @@ -34,6 +36,11 @@ contract PerpsMarketFactoryModule is IPerpsMarketFactoryModule { using GlobalPerpsMarket for GlobalPerpsMarket.Data; using PerpsPrice for PerpsPrice.Data; using DecimalMath for uint256; + using SafeCastU256 for uint256; + using SafeCastU128 for uint128; + using SafeCastI256 for int256; + using SetUtil for SetUtil.UintSet; + using PerpsMarket for PerpsMarket.Data; bytes32 private constant _CREATE_MARKET_FEATURE_FLAG = "createMarket"; @@ -101,11 +108,33 @@ contract PerpsMarketFactoryModule is IPerpsMarketFactoryModule { function name(uint128 perpsMarketId) external view override returns (string memory) { // todo: set name on initialize? + perpsMarketId; // silence unused variable warning return "Perps Market"; } function reportedDebt(uint128 perpsMarketId) external view override returns (uint256) { - // TODO + PerpsMarketFactory.Data storage factory = PerpsMarketFactory.load(); + + if (factory.perpsMarketId == perpsMarketId) { + // debt is the total debt of all markets + // can be computed as total collateral value - sum_each_market( debt ) + uint totalCollateralValue = GlobalPerpsMarket.load().totalCollateralValue(); + int totalMarketDebt; + + SetUtil.UintSet storage activeMarkets = GlobalPerpsMarket.load().activeMarkets; + uint256 activeMarketsLength = activeMarkets.length(); + for (uint i = 1; i <= activeMarketsLength; i++) { + uint128 marketId = activeMarkets.valueAt(i).to128(); + totalMarketDebt += PerpsMarket.load(marketId).marketDebt( + PerpsPrice.getCurrentPrice(marketId) + ); + } + + int totalDebt = totalCollateralValue.toInt() + totalMarketDebt; + return totalDebt < 0 ? 0 : totalDebt.toUint(); + } + + // TODO Should revert if perpsMarketId is not correct??? return 0; } diff --git a/markets/perps-market/contracts/storage/GlobalPerpsMarket.sol b/markets/perps-market/contracts/storage/GlobalPerpsMarket.sol index 36dd7a74a8..77ad14a244 100644 --- a/markets/perps-market/contracts/storage/GlobalPerpsMarket.sol +++ b/markets/perps-market/contracts/storage/GlobalPerpsMarket.sol @@ -66,7 +66,7 @@ library GlobalPerpsMarket { ISpotMarketSystem spotMarket = PerpsMarketFactory.load().spotMarket; SetUtil.UintSet storage activeCollateralTypes = self.activeCollateralTypes; uint256 activeCollateralLength = activeCollateralTypes.length(); - for (uint i = 1; i < activeCollateralLength; i++) { + for (uint i = 1; i <= activeCollateralLength; i++) { uint128 synthMarketId = activeCollateralTypes.valueAt(i).to128(); if (synthMarketId == 0) { diff --git a/markets/perps-market/contracts/storage/PerpsAccount.sol b/markets/perps-market/contracts/storage/PerpsAccount.sol index 5fe986cd90..d49d72eee5 100644 --- a/markets/perps-market/contracts/storage/PerpsAccount.sol +++ b/markets/perps-market/contracts/storage/PerpsAccount.sol @@ -188,7 +188,7 @@ library PerpsAccount { for (uint i = 1; i <= self.openPositionMarketIds.length(); i++) { uint128 marketId = self.openPositionMarketIds.valueAt(i).to128(); Position.Data storage position = PerpsMarket.load(marketId).positions[self.id]; - (int pnl, , , ) = position.getPnl(PerpsPrice.getCurrentPrice(marketId)); + (int pnl, , , , ) = position.getPnl(PerpsPrice.getCurrentPrice(marketId)); totalPnl += pnl; } } @@ -207,7 +207,7 @@ library PerpsAccount { uint128 marketId = self.openPositionMarketIds.valueAt(i).to128(); Position.Data storage position = PerpsMarket.load(marketId).positions[self.id]; - (uint openInterest, , , , ) = position.getPositionData( + (uint openInterest, , , , , ) = position.getPositionData( PerpsPrice.getCurrentPrice(marketId) ); totalAccountOpenInterest += openInterest; diff --git a/markets/perps-market/contracts/storage/PerpsMarket.sol b/markets/perps-market/contracts/storage/PerpsMarket.sol index 5efebe9ed4..696bfa1c4b 100644 --- a/markets/perps-market/contracts/storage/PerpsMarket.sol +++ b/markets/perps-market/contracts/storage/PerpsMarket.sol @@ -36,12 +36,18 @@ library PerpsMarket { uint128 id; int256 skew; uint256 size; - int lastFundingRate; - int lastFundingValue; + // TODO: move to new data structure? + int256 lastFundingRate; + int256 lastFundingValue; uint256 lastFundingTime; // liquidation data uint128 lastTimeLiquidationCapacityUpdated; uint128 lastUtilizedLiquidationCapacity; + // debt calculation + // accumulates total notional size of the market including accrued funding until the last time any position changed + int256 debtCorrectionAccumulator; + // accountId => asyncOrder + mapping(uint => AsyncOrder.Data) asyncOrders; // accountId => position mapping(uint => Position.Data) positions; } @@ -139,7 +145,9 @@ library PerpsMarket { } /** - * @dev If you call this method, please ensure you emit an event so offchain solution can index market state history properly + * @dev Use this function to update both market/position size/skew. + * @dev Size and skew should not be updated directly. + * @dev The return value is used to emit a MarketUpdated event. */ function updatePositionData( Data storage self, @@ -147,12 +155,24 @@ library PerpsMarket { Position.Data memory newPosition ) internal returns (MarketUpdateData memory) { Position.Data storage oldPosition = self.positions[accountId]; + int128 oldPositionSize = oldPosition.size; int128 newPositionSize = newPosition.size; self.size = (self.size + MathUtil.abs(newPositionSize)) - MathUtil.abs(oldPositionSize); self.skew += newPositionSize - oldPositionSize; + uint currentPrice = newPosition.latestInteractionPrice; + (int totalPositionPnl, , , , ) = oldPosition.getPnl(currentPrice); + + int sizeDelta = newPositionSize - oldPositionSize; + int fundingDelta = calculateNextFunding(self, currentPrice).mulDecimal(sizeDelta); + int notionalDelta = currentPrice.toInt().mulDecimal(sizeDelta); + + // update the market debt correction accumulator before losing oldPosition details + // by adding the new updated notional (old - new size) plus old position pnl + self.debtCorrectionAccumulator += fundingDelta + notionalDelta + totalPositionPnl; + oldPosition.update(newPosition); return @@ -280,4 +300,17 @@ library PerpsMarket { } } } + + /** + * @dev Returns the market debt incurred by all positions + * @notice Market debt is the sum of all position sizes multiplied by the price, and old positions pnl that is included in the debt correction accumulator. + */ + function marketDebt(Data storage self, uint price) internal view returns (int) { + // all positions sizes multiplied by the price is equivalent to skew times price + // and the debt correction accumulator is the sum of all positions pnl + int traderUnrealizedPnl = self.skew.mulDecimal(price.toInt()); + int unrealizedFunding = self.skew.mulDecimal(calculateNextFunding(self, price)); + + return traderUnrealizedPnl + unrealizedFunding - self.debtCorrectionAccumulator; + } } diff --git a/markets/perps-market/contracts/storage/Position.sol b/markets/perps-market/contracts/storage/Position.sol index b333102473..61df4de0d9 100644 --- a/markets/perps-market/contracts/storage/Position.sol +++ b/markets/perps-market/contracts/storage/Position.sol @@ -47,26 +47,38 @@ library Position { view returns ( uint256 notionalValue, - int pnl, + int totalPnl, + int pricePnl, int accruedFunding, int netFundingPerUnit, int nextFunding ) { - (pnl, accruedFunding, netFundingPerUnit, nextFunding) = getPnl(self, price); + (totalPnl, pricePnl, accruedFunding, netFundingPerUnit, nextFunding) = getPnl(self, price); notionalValue = getNotionalValue(self, price); } function getPnl( Data storage self, uint price - ) internal view returns (int pnl, int accruedFunding, int netFundingPerUnit, int nextFunding) { + ) + internal + view + returns ( + int totalPnl, + int pricePnl, + int accruedFunding, + int netFundingPerUnit, + int nextFunding + ) + { nextFunding = PerpsMarket.load(self.marketId).calculateNextFunding(price); netFundingPerUnit = nextFunding - self.latestInteractionFunding; accruedFunding = self.size.mulDecimal(netFundingPerUnit); int priceShift = price.toInt() - self.latestInteractionPrice.toInt(); - pnl = self.size.mulDecimal(priceShift) + accruedFunding; + pricePnl = self.size.mulDecimal(priceShift); + totalPnl = pricePnl + accruedFunding; } function getNotionalValue(Data storage self, uint256 price) internal view returns (uint256) { diff --git a/markets/perps-market/storage.dump.sol b/markets/perps-market/storage.dump.sol index c5d93f6943..5579446c2d 100644 --- a/markets/perps-market/storage.dump.sol +++ b/markets/perps-market/storage.dump.sol @@ -575,11 +575,13 @@ library PerpsMarket { uint128 id; int256 skew; uint256 size; - int lastFundingRate; - int lastFundingValue; + int256 lastFundingRate; + int256 lastFundingValue; uint256 lastFundingTime; uint128 lastTimeLiquidationCapacityUpdated; uint128 lastUtilizedLiquidationCapacity; + int256 debtCorrectionAccumulator; + mapping(uint => AsyncOrder.Data) asyncOrders; mapping(uint => Position.Data) positions; } struct MarketUpdateData { diff --git a/markets/perps-market/test/integration/Market/MarketDebt.test.ts b/markets/perps-market/test/integration/Market/MarketDebt.test.ts new file mode 100644 index 0000000000..4db8929b31 --- /dev/null +++ b/markets/perps-market/test/integration/Market/MarketDebt.test.ts @@ -0,0 +1,341 @@ +import { PerpsMarket, bn, bootstrapMarkets } from '../bootstrap'; +import { OpenPositionData, depositCollateral, openPosition } from '../helpers'; +import assertBn from '@synthetixio/core-utils/utils/assertions/assert-bignumber'; +import { Signer, ethers } from 'ethers'; +import { snapshotCheckpoint } from '@synthetixio/core-utils/utils/mocha/snapshot'; + +describe('Market Debt - single market', () => { + const orderFees = { + makerFee: bn(0.0), // 0bps no fees + takerFee: bn(0.0), // 0bps no fees + }; + + const { systems, superMarketId, perpsMarkets, provider, trader1, trader2, trader3, keeper } = + bootstrapMarkets({ + synthMarkets: [ + { + name: 'Bitcoin', + token: 'snxBTC', + buyPrice: bn(10_000), + sellPrice: bn(10_000), + }, + ], + perpsMarkets: [ + { + requestedMarketId: bn(25), + name: 'Ether', + token: 'snxETH', + price: bn(1000), + // setting to 0 to avoid funding and p/d price change affecting pnl + fundingParams: { skewScale: bn(0), maxFundingVelocity: bn(0) }, + orderFees, + settlementStrategy: { + settlementReward: bn(0), + priceDeviationTolerance: bn(50), + }, + }, + ], + traderAccountIds: [2, 3, 4], + }); + + let perpsMarket: PerpsMarket; + + before('identify actors', async () => { + perpsMarket = perpsMarkets()[0]; + }); + + const marketActivities: Array<{ + name: string; + user?: { + trader: () => Signer; + accountId: number; + collateralDelta?: ethers.BigNumber; // amount of collateral to deposit or withdraw in the step + sizeDelta?: ethers.BigNumber; // position size change to open or close in the step + }; + market?: { price: ethers.BigNumber }; // market to change the price and new price + expected?: { + // expected results to check on the step + marketDebt: ethers.BigNumber; + }; + }> = [ + { + name: 'initial state', + market: { + price: bn(1000), + }, + expected: { + marketDebt: bn(0), + }, + }, + { + name: 'acc1 deposits 1000', + user: { + trader: trader1, + accountId: 2, + collateralDelta: bn(1000), + }, + market: { + price: bn(1000), + }, + expected: { + marketDebt: bn(1000), // 1000 deposited + }, + }, + { + name: 'acc1 opens 10x 10 long eth at 1000', + user: { + trader: trader1, + accountId: 2, + sizeDelta: bn(10), + }, + market: { + price: bn(1000), + }, + expected: { + marketDebt: bn(1000), // 1000 deposited + }, + }, + { + name: 'eth price change to 1200', + market: { + price: bn(1200), + }, + expected: { + marketDebt: bn(3000), // 1000 deposited + 2000 pnl + }, + }, + { + name: 'acc2 deposits 1200', + user: { + trader: trader2, + accountId: 3, + collateralDelta: bn(1200), + }, + market: { + price: bn(1200), + }, + expected: { + marketDebt: bn(4200), // 2200 deposited + 2000 pnl + }, + }, + { + name: 'acc2 opens 10x short 5 eth at 1200', + user: { + trader: trader2, + accountId: 3, + sizeDelta: bn(-5), + }, + market: { + price: bn(1200), + }, + expected: { + marketDebt: bn(4200), // 2200 deposited + 2000 pnl + 0 pnl + }, + }, + { + name: 'eht price change to 1100', + market: { + price: bn(1100), + }, + expected: { + marketDebt: bn(3700), // 2200 deposited + 1000 pnl + 500 pnl + }, + }, + { + name: 'acc3 deposits 3300', + user: { + trader: trader3, + accountId: 4, + collateralDelta: bn(3300), + }, + market: { + price: bn(1100), + }, + expected: { + marketDebt: bn(7000), // 5500 deposited + 1000 pnl + 500 pnl + }, + }, + { + name: 'acc3 opens 10x short 10 eth at 1100', + user: { + trader: trader3, + accountId: 4, + sizeDelta: bn(-10), + }, + market: { + price: bn(1100), + }, + expected: { + marketDebt: bn(7000), // 5500 deposited + 1000 pnl + 500 pnl + 0 pnl + }, + }, + { + name: 'eth price change to 1000', + market: { + price: bn(1000), + }, + expected: { + marketDebt: bn(7500), // 5500 deposited + 0 pnl + 1000 pnl + 1000 pnl + }, + }, + { + name: 'acc2 closes short', + user: { + trader: trader2, + accountId: 3, + sizeDelta: bn(5), + }, + market: { + price: bn(1000), + }, + expected: { + marketDebt: bn(7500), // 5500 deposited + 0 pnl + 1000 pnl_fixed + 1000 pnl + }, + }, + { + name: 'acc2 withdraw 1200 + 1000 (pnl)', + user: { + trader: trader2, + accountId: 3, + collateralDelta: bn(-2200), + }, + market: { + price: bn(1000), + }, + expected: { + marketDebt: bn(5300), // 4300 deposited + 0 pnl + 1000 pnl + }, + }, + { + name: 'eth price change to 1200', + market: { + price: bn(1200), + }, + expected: { + marketDebt: bn(5300), // 4300 deposited + 2000 pnl - 1000 pnl + }, + }, + { + name: 'acc3 closes short', + user: { + trader: trader3, + accountId: 4, + sizeDelta: bn(10), + }, + market: { + price: bn(1200), + }, + expected: { + marketDebt: bn(5300), // 4300 deposited + 2000 pnl - 1000 pnl_fixed + }, + }, + { + name: 'acc3 withdraw 3300 - 1000 (pnl)', + user: { + trader: trader3, + accountId: 4, + collateralDelta: bn(-2300), + }, + market: { + price: bn(1200), + }, + expected: { + marketDebt: bn(3000), // 1000 deposited + 2000 pnl + }, + }, + { + name: 'eth price change to 900', + market: { + price: bn(900), + }, + expected: { + marketDebt: bn(0), // 1000 deposited - 1000 pnl + }, + }, + { + name: 'acc1 closes long', + user: { + trader: trader1, + accountId: 2, + sizeDelta: bn(-10), + }, + market: { + price: bn(900), + }, + expected: { + marketDebt: bn(0), // 1000 deposited - 1000 pnl + }, + }, + ]; + + describe(`Using snxUSD as collateral`, () => { + let commonOpenPositionProps: Pick< + OpenPositionData, + 'systems' | 'provider' | 'keeper' | 'settlementStrategyId' | 'marketId' + >; + const restoreActivities = snapshotCheckpoint(provider); + + before('identify common props', async () => { + commonOpenPositionProps = { + systems, + provider, + settlementStrategyId: perpsMarket.strategyId(), + keeper: keeper(), + marketId: perpsMarket.marketId(), + }; + }); + + marketActivities.forEach((marketActivity) => { + describe(`Market Activity Step: ${marketActivity.name}`, () => { + before('set price', async () => { + if ( + marketActivity.market && + marketActivity.market.price && + !marketActivity.market.price.isZero() + ) { + await perpsMarket.aggregator().mockSetCurrentPrice(marketActivity.market.price); + } + }); + + before('update collateral', async () => { + if ( + marketActivity.user && + marketActivity.user.collateralDelta && + !marketActivity.user.collateralDelta.isZero() + ) { + await depositCollateral({ + systems, + trader: marketActivity.user!.trader, + accountId: () => marketActivity.user!.accountId, + collaterals: [{ snxUSDAmount: () => marketActivity.user!.collateralDelta! }], + }); + } + }); + + before('update position', async () => { + if ( + marketActivity.user && + marketActivity.user.sizeDelta && + !marketActivity.user.sizeDelta.isZero() + ) { + await openPosition({ + ...commonOpenPositionProps, + trader: marketActivity.user!.trader(), + accountId: marketActivity.user!.accountId, + sizeDelta: marketActivity.user!.sizeDelta!, + price: marketActivity.market!.price, + }); + } + }); + + it('should have correct market debt', async () => { + assertBn.equal( + await systems().PerpsMarket.reportedDebt(superMarketId()), + marketActivity.expected!.marketDebt + ); + }); + }); + }); + after(restoreActivities); + }); +}); diff --git a/markets/perps-market/test/integration/Market/MarketDebt.withFunding.test.ts b/markets/perps-market/test/integration/Market/MarketDebt.withFunding.test.ts new file mode 100644 index 0000000000..7b231ac665 --- /dev/null +++ b/markets/perps-market/test/integration/Market/MarketDebt.withFunding.test.ts @@ -0,0 +1,298 @@ +import { fastForwardTo, getTxTime } from '@synthetixio/core-utils/utils/hardhat/rpc'; +import { PerpsMarket, bn, bootstrapMarkets } from '../bootstrap'; +import { openPosition } from '../helpers'; +import assertBn from '@synthetixio/core-utils/utils/assertions/assert-bignumber'; +import { ethers } from 'ethers'; + +const _SKEW_SCALE = bn(25_000); +const _MAX_FUNDING_VELOCITY = bn(3); +const _SECONDS_IN_DAY = 24 * 60 * 60; + +describe('Market Debt - with funding', () => { + const traderAccountIds = [2, 3, 4]; + const { systems, superMarketId, perpsMarkets, provider, trader1, trader2, trader3, keeper } = + bootstrapMarkets({ + synthMarkets: [ + { + name: 'Bitcoin', + token: 'snxBTC', + buyPrice: bn(10_000), + sellPrice: bn(10_000), + }, + ], + perpsMarkets: [ + { + requestedMarketId: bn(25), + name: 'Ether', + token: 'snxETH', + price: bn(1000), + // setting to 0 to avoid funding and p/d price change affecting pnl + orderFees: { + makerFee: bn(0.0005), // 0bps no fees + takerFee: bn(0.00025), + }, + fundingParams: { skewScale: _SKEW_SCALE, maxFundingVelocity: _MAX_FUNDING_VELOCITY }, + liquidationParams: { + initialMarginFraction: bn(3), + maintenanceMarginFraction: bn(2), + maxLiquidationLimitAccumulationMultiplier: bn(1), + liquidationRewardRatio: bn(0.05), + maxSecondsInLiquidationWindow: ethers.BigNumber.from(10), + minimumPositionMargin: bn(0), + }, + settlementStrategy: { + settlementReward: bn(0), + }, + }, + ], + traderAccountIds, + }); + + let perpsMarket: PerpsMarket; + before('identify actors', () => { + perpsMarket = perpsMarkets()[0]; + }); + + before('add collateral to margin', async () => { + await systems().PerpsMarket.connect(trader1()).modifyCollateral(2, 0, bn(10_000)); + await systems().PerpsMarket.connect(trader2()).modifyCollateral(3, 0, bn(10_000)); + await systems().PerpsMarket.connect(trader3()).modifyCollateral(4, 0, bn(100_000)); + }); + + describe('with no positions', () => { + it('should report total collateral value as debt', async () => { + const debt = await systems().PerpsMarket.reportedDebt(superMarketId()); + assertBn.equal(debt, bn(120_000)); + }); + }); + + let openPositionTime: number; + describe('open positions', () => { + before(async () => { + await openPosition({ + systems, + provider, + trader: trader1(), + accountId: 2, + keeper: keeper(), + marketId: perpsMarket.marketId(), + sizeDelta: bn(150), + settlementStrategyId: perpsMarket.strategyId(), + price: bn(1000), + }); + await openPosition({ + systems, + provider, + trader: trader2(), + accountId: 3, + keeper: keeper(), + marketId: perpsMarket.marketId(), + sizeDelta: bn(-50), + settlementStrategyId: perpsMarket.strategyId(), + price: bn(1000), + }); + openPositionTime = await openPosition({ + systems, + provider, + trader: trader3(), + accountId: 4, + keeper: keeper(), + marketId: perpsMarket.marketId(), + sizeDelta: bn(200), + settlementStrategyId: perpsMarket.strategyId(), + price: bn(1000), + }); + }); + + let unrealizedTraderPnl: ethers.BigNumber, totalCollateralValue: ethers.BigNumber; + before('get unrealized trader pnl', async () => { + const [trader1Pnl] = await systems().PerpsMarket.getOpenPosition(2, perpsMarket.marketId()); + const [trader2Pnl] = await systems().PerpsMarket.getOpenPosition(3, perpsMarket.marketId()); + const [trader3Pnl] = await systems().PerpsMarket.getOpenPosition(4, perpsMarket.marketId()); + unrealizedTraderPnl = trader1Pnl.add(trader2Pnl).add(trader3Pnl); + totalCollateralValue = await systems().PerpsMarket.totalGlobalCollateralValue(); + }); + + it('reports correct debt', async () => { + const debt = await systems().PerpsMarket.reportedDebt(superMarketId()); + assertBn.near(debt, totalCollateralValue.add(unrealizedTraderPnl), bn(0.0001)); + }); + }); + + describe('a day goes by', () => { + before('fast forward', async () => { + await fastForwardTo(openPositionTime + _SECONDS_IN_DAY, provider()); + }); + + let unrealizedTraderPnl: ethers.BigNumber, totalCollateralValue: ethers.BigNumber; + before('get unrealized trader pnl', async () => { + const [trader1Pnl] = await systems().PerpsMarket.getOpenPosition(2, perpsMarket.marketId()); + const [trader2Pnl] = await systems().PerpsMarket.getOpenPosition(3, perpsMarket.marketId()); + const [trader3Pnl] = await systems().PerpsMarket.getOpenPosition(4, perpsMarket.marketId()); + unrealizedTraderPnl = trader1Pnl.add(trader2Pnl).add(trader3Pnl); + totalCollateralValue = await systems().PerpsMarket.totalGlobalCollateralValue(); + }); + + it('reports correct debt', async () => { + const debt = await systems().PerpsMarket.reportedDebt(superMarketId()); + assertBn.near(debt, totalCollateralValue.add(unrealizedTraderPnl), bn(0.0001)); + }); + }); + + describe('price change', () => { + before('change price', async () => { + await perpsMarket.aggregator().mockSetCurrentPrice(bn(1050)); + }); + + let unrealizedTraderPnl: ethers.BigNumber, totalCollateralValue: ethers.BigNumber; + before('get unrealized trader pnl', async () => { + const [trader1Pnl] = await systems().PerpsMarket.getOpenPosition(2, perpsMarket.marketId()); + const [trader2Pnl] = await systems().PerpsMarket.getOpenPosition(3, perpsMarket.marketId()); + const [trader3Pnl] = await systems().PerpsMarket.getOpenPosition(4, perpsMarket.marketId()); + unrealizedTraderPnl = trader1Pnl.add(trader2Pnl).add(trader3Pnl); + totalCollateralValue = await systems().PerpsMarket.totalGlobalCollateralValue(); + }); + + it('reports correct debt', async () => { + const debt = await systems().PerpsMarket.reportedDebt(superMarketId()); + assertBn.near(debt, totalCollateralValue.add(unrealizedTraderPnl), bn(0.0001)); + }); + }); + + describe('reduce trader 3 position', () => { + before(async () => { + await openPosition({ + systems, + provider, + trader: trader3(), + accountId: 4, + keeper: keeper(), + marketId: perpsMarket.marketId(), + sizeDelta: bn(-50), + settlementStrategyId: perpsMarket.strategyId(), + price: bn(1050), + }); + }); + + let unrealizedTraderPnl: ethers.BigNumber, totalCollateralValue: ethers.BigNumber; + before('get unrealized trader pnl', async () => { + const [trader1Pnl] = await systems().PerpsMarket.getOpenPosition(2, perpsMarket.marketId()); + const [trader2Pnl] = await systems().PerpsMarket.getOpenPosition(3, perpsMarket.marketId()); + const [trader3Pnl] = await systems().PerpsMarket.getOpenPosition(4, perpsMarket.marketId()); + totalCollateralValue = await systems().PerpsMarket.totalGlobalCollateralValue(); + unrealizedTraderPnl = trader1Pnl.add(trader2Pnl).add(trader3Pnl); + }); + + it('reports correct debt', async () => { + const debt = await systems().PerpsMarket.reportedDebt(superMarketId()); + assertBn.equal(debt, totalCollateralValue.add(unrealizedTraderPnl)); + }); + }); + + describe('short more eth trader 2 position', () => { + before('trader 2 adds more size', async () => { + await openPosition({ + systems, + provider, + trader: trader2(), + accountId: 3, + keeper: keeper(), + marketId: perpsMarket.marketId(), + sizeDelta: bn(-50), + settlementStrategyId: perpsMarket.strategyId(), + price: bn(1050), + }); + }); + + let unrealizedTraderPnl: ethers.BigNumber, totalCollateralValue: ethers.BigNumber; + before('get unrealized trader pnl', async () => { + const [trader1Pnl] = await systems().PerpsMarket.getOpenPosition(2, perpsMarket.marketId()); + const [trader2Pnl] = await systems().PerpsMarket.getOpenPosition(3, perpsMarket.marketId()); + const [trader3Pnl] = await systems().PerpsMarket.getOpenPosition(4, perpsMarket.marketId()); + totalCollateralValue = await systems().PerpsMarket.totalGlobalCollateralValue(); + unrealizedTraderPnl = trader1Pnl.add(trader2Pnl).add(trader3Pnl); + }); + + it('reports correct debt', async () => { + const debt = await systems().PerpsMarket.reportedDebt(superMarketId()); + assertBn.equal(debt, totalCollateralValue.add(unrealizedTraderPnl)); + }); + }); + + describe('trader 2 gets liquidated', () => { + before('change price', async () => { + await perpsMarket.aggregator().mockSetCurrentPrice(bn(1135)); + await systems().PerpsMarket.connect(keeper()).liquidate(3); + }); + + let unrealizedTraderPnl: ethers.BigNumber, totalCollateralValue: ethers.BigNumber; + before('get unrealized trader pnl', async () => { + const [trader1Pnl] = await systems().PerpsMarket.getOpenPosition(2, perpsMarket.marketId()); + const [trader2Pnl] = await systems().PerpsMarket.getOpenPosition(3, perpsMarket.marketId()); + const [trader3Pnl] = await systems().PerpsMarket.getOpenPosition(4, perpsMarket.marketId()); + totalCollateralValue = await systems().PerpsMarket.totalGlobalCollateralValue(); + unrealizedTraderPnl = trader1Pnl.add(trader2Pnl).add(trader3Pnl); + }); + + it('reports correct debt', async () => { + const debt = await systems().PerpsMarket.reportedDebt(superMarketId()); + assertBn.equal(debt, totalCollateralValue.add(unrealizedTraderPnl)); + }); + }); + + let partialLiquidationTime: number; + describe('trader 1 gets partially liquidated', () => { + before('change price', async () => { + await perpsMarket.aggregator().mockSetCurrentPrice(bn(950)); + const liquidateTxn = await systems().PerpsMarket.connect(keeper()).liquidate(2); + partialLiquidationTime = await getTxTime(provider(), liquidateTxn); + }); + + let unrealizedTraderPnl: ethers.BigNumber, totalCollateralValue: ethers.BigNumber; + before('get unrealized trader pnl', async () => { + const [trader1Pnl] = await systems().PerpsMarket.getOpenPosition(2, perpsMarket.marketId()); + const [trader2Pnl] = await systems().PerpsMarket.getOpenPosition(3, perpsMarket.marketId()); + const [trader3Pnl] = await systems().PerpsMarket.getOpenPosition(4, perpsMarket.marketId()); + totalCollateralValue = await systems().PerpsMarket.totalGlobalCollateralValue(); + unrealizedTraderPnl = trader1Pnl.add(trader2Pnl).add(trader3Pnl); + }); + + it('reports correct debt', async () => { + const debt = await systems().PerpsMarket.reportedDebt(superMarketId()); + assertBn.near(debt, totalCollateralValue.add(unrealizedTraderPnl), bn(0.000001)); + }); + }); + + describe('trader 1 gets fully liquidated', () => { + before('move forward by a day', async () => { + await fastForwardTo(partialLiquidationTime + _SECONDS_IN_DAY, provider()); + }); + + before('price change', async () => { + await perpsMarket.aggregator().mockSetCurrentPrice(bn(930)); + }); + + before('liquidate trader 1 again', async () => { + await systems().PerpsMarket.connect(keeper()).liquidate(2); + }); + + let unrealizedTraderPnl: ethers.BigNumber, totalCollateralValue: ethers.BigNumber; + before('get unrealized trader pnl', async () => { + const [trader1Pnl] = await systems().PerpsMarket.getOpenPosition(2, perpsMarket.marketId()); + const [trader2Pnl] = await systems().PerpsMarket.getOpenPosition(3, perpsMarket.marketId()); + const [trader3Pnl] = await systems().PerpsMarket.getOpenPosition(4, perpsMarket.marketId()); + totalCollateralValue = await systems().PerpsMarket.totalGlobalCollateralValue(); + unrealizedTraderPnl = trader1Pnl.add(trader2Pnl).add(trader3Pnl); + }); + + it('reports correct debt', async () => { + const debt = await systems().PerpsMarket.reportedDebt(superMarketId()); + assertBn.near(debt, totalCollateralValue.add(unrealizedTraderPnl), bn(0.000001)); + }); + + it('fully liquidated trader 1', async () => { + const positionData = await systems().PerpsMarket.getOpenPosition(2, perpsMarket.marketId()); + assertBn.equal(positionData.positionSize, bn(0)); + }); + }); +}); diff --git a/markets/perps-market/test/integration/bootstrap/bootstrap.ts b/markets/perps-market/test/integration/bootstrap/bootstrap.ts index c6d3cca9df..a1af4ce9e1 100644 --- a/markets/perps-market/test/integration/bootstrap/bootstrap.ts +++ b/markets/perps-market/test/integration/bootstrap/bootstrap.ts @@ -91,7 +91,7 @@ export function bootstrapMarkets(data: BootstrapArgs) { const { systems, signers, provider, owner, perpsMarkets, marketOwner, poolId, superMarketId } = chainStateWithPerpsMarkets; - const { trader1, trader2, keeper, restore } = bootstrapTraders({ + const { trader1, trader2, trader3, keeper, restore } = bootstrapTraders({ systems, signers, provider, @@ -145,6 +145,7 @@ export function bootstrapMarkets(data: BootstrapArgs) { restore, trader1, trader2, + trader3, keeper, owner, perpsMarkets, diff --git a/markets/perps-market/test/integration/bootstrap/bootstrapTraders.ts b/markets/perps-market/test/integration/bootstrap/bootstrapTraders.ts index 200d299b93..1ff8908279 100644 --- a/markets/perps-market/test/integration/bootstrap/bootstrapTraders.ts +++ b/markets/perps-market/test/integration/bootstrap/bootstrapTraders.ts @@ -19,10 +19,10 @@ export function bootstrapTraders(data: Data) { const { systems, signers, provider, accountIds, owner } = data; bootstrapStakers(systems, signers, bn(100_000)); - let trader1: ethers.Signer, trader2: ethers.Signer, keeper: ethers.Signer; + let trader1: ethers.Signer, trader2: ethers.Signer, trader3: ethers.Signer, keeper: ethers.Signer; before('provide access to create account', async () => { - [, , , trader1, trader2, keeper] = signers(); + [, , , trader1, trader2, trader3, keeper] = signers(); await systems() .PerpsMarket.connect(owner()) .addToFeatureFlagAllowlist( @@ -35,10 +35,16 @@ export function bootstrapTraders(data: Data) { ethers.utils.formatBytes32String('createAccount'), trader2.getAddress() ); + await systems() + .PerpsMarket.connect(owner()) + .addToFeatureFlagAllowlist( + ethers.utils.formatBytes32String('createAccount'), + trader3.getAddress() + ); }); before('infinite approve to perps/spot market proxy', async () => { - [, , , trader1, trader2] = signers(); + [, , , trader1, trader2, trader3] = signers(); await systems() .USD.connect(trader1) .approve(systems().PerpsMarket.address, ethers.constants.MaxUint256); @@ -51,11 +57,19 @@ export function bootstrapTraders(data: Data) { await systems() .USD.connect(trader2) .approve(systems().SpotMarket.address, ethers.constants.MaxUint256); + await systems() + .USD.connect(trader3) + .approve(systems().PerpsMarket.address, ethers.constants.MaxUint256); + await systems() + .USD.connect(trader3) + .approve(systems().SpotMarket.address, ethers.constants.MaxUint256); }); accountIds.forEach((id, idx) => { before(`create account ${id}`, async () => { - await systems().PerpsMarket.connect([trader1, trader2][idx])['createAccount(uint128)'](id); + await systems() + .PerpsMarket.connect([trader1, trader2, trader3][idx]) + ['createAccount(uint128)'](id); // eslint-disable-line no-unexpected-multiline }); }); @@ -64,6 +78,7 @@ export function bootstrapTraders(data: Data) { return { trader1: () => trader1, trader2: () => trader2, + trader3: () => trader3, keeper: () => keeper, restore, }; diff --git a/protocol/synthetix/contracts/interfaces/external/IMarket.sol b/protocol/synthetix/contracts/interfaces/external/IMarket.sol index 79776a442f..e4abc6a4ed 100644 --- a/protocol/synthetix/contracts/interfaces/external/IMarket.sol +++ b/protocol/synthetix/contracts/interfaces/external/IMarket.sol @@ -8,7 +8,7 @@ interface IMarket is IERC165 { /// @notice returns a human-readable name for a given market function name(uint128 marketId) external view returns (string memory); - /// @notice returns amount of USD that the market would try to mint256 if everything was withdrawn + /// @notice returns amount of USD that the market would try to mint if everything was withdrawn function reportedDebt(uint128 marketId) external view returns (uint256); /// @notice prevents reduction of available credit capacity by specifying this amount, for which withdrawals will be disallowed diff --git a/protocol/synthetix/test/common/stakers.ts b/protocol/synthetix/test/common/stakers.ts index 3c76aff847..61b5bd07d6 100644 --- a/protocol/synthetix/test/common/stakers.ts +++ b/protocol/synthetix/test/common/stakers.ts @@ -13,11 +13,11 @@ export function bootstrapStakers( signers: () => ethers.Signer[], delegateAmount: ethers.BigNumber = depositAmount ) { - let staker1: ethers.Signer, staker2: ethers.Signer; + let staker1: ethers.Signer, staker2: ethers.Signer, staker3: ethers.Signer; before('identify stakers', () => { - [, , , staker1, staker2] = signers(); + [, , , staker1, staker2, staker3] = signers(); }); - // create new bool + // create new pool before('create separate pool', async () => { const [owner] = signers(); await systems() @@ -28,6 +28,7 @@ export function bootstrapStakers( before('create traders', async () => { await stake(systems(), 2, 1000, staker1, delegateAmount); await stake(systems(), 2, 1001, staker2, delegateAmount); + await stake(systems(), 2, 1002, staker3, delegateAmount); }); before('mint usd', async () => { @@ -38,6 +39,9 @@ export function bootstrapStakers( await systems() .Core.connect(staker2) .mintUsd(1001, 2, collateralAddress, delegateAmount.mul(200)); + await systems() + .Core.connect(staker3) + .mintUsd(1002, 2, collateralAddress, delegateAmount.mul(200)); }); } From 3992cfad90c2a1bf9b3f1daddb7de680ae593b3a Mon Sep 17 00:00:00 2001 From: Sunny Vempati Date: Mon, 31 Jul 2023 09:23:00 -0500 Subject: [PATCH 19/63] fix signer position (#1735) --- markets/spot-market/test/AsyncOrderModule.onchain.test.ts | 2 +- markets/spot-market/test/AtomicOrderModule.referrer.test.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/markets/spot-market/test/AsyncOrderModule.onchain.test.ts b/markets/spot-market/test/AsyncOrderModule.onchain.test.ts index 3f70975779..3c3b26bac8 100644 --- a/markets/spot-market/test/AsyncOrderModule.onchain.test.ts +++ b/markets/spot-market/test/AsyncOrderModule.onchain.test.ts @@ -36,7 +36,7 @@ describe('AsyncOrderModule onchain', () => { strategyId: number; before('identify', async () => { - [, , marketOwner, trader1, , keeper] = signers(); + [, , marketOwner, trader1, , , , keeper] = signers(); const synthAddress = await systems().SpotMarket.getSynth(marketId()); synth = systems().Synth(synthAddress); }); diff --git a/markets/spot-market/test/AtomicOrderModule.referrer.test.ts b/markets/spot-market/test/AtomicOrderModule.referrer.test.ts index 1c12eec468..877fc10831 100644 --- a/markets/spot-market/test/AtomicOrderModule.referrer.test.ts +++ b/markets/spot-market/test/AtomicOrderModule.referrer.test.ts @@ -16,7 +16,7 @@ describe('Atomic Order Module referrer', () => { let synth: SynthRouter; before('identify actors', async () => { - [, , marketOwner, trader1, trader2, referrer] = signers(); + [, , marketOwner, trader1, trader2, , , , , referrer] = signers(); }); before('identify synth', async () => { From 11da4a340eddccae53d4b87ca421420e219b869b Mon Sep 17 00:00:00 2001 From: Sunny Vempati Date: Mon, 31 Jul 2023 12:15:15 -0500 Subject: [PATCH 20/63] async order fee collector (#1733) * async order refactor * fix caller on sm * fix tests and fee collector * remove only * test * code review fixes * remove only --- markets/perps-market/cannonfile.test.toml | 3 + .../interfaces/IAsyncOrderModule.sol | 28 +- .../IAsyncOrderSettlementModule.sol | 19 +- .../interfaces/IGlobalPerpsMarketModule.sol | 50 +++ .../interfaces/external/IFeeCollector.sol | 20 + .../contracts/mocks/FeeCollectorMock.sol | 34 ++ .../contracts/modules/AsyncOrderModule.sol | 40 +- .../modules/AsyncOrderSettlementModule.sol | 97 ++--- .../modules/GlobalPerpsMarketModule.sol | 51 +++ .../contracts/modules/PerpsAccountModule.sol | 2 +- .../contracts/storage/AsyncOrder.sol | 179 ++++---- .../GlobalPerpsMarketConfiguration.sol | 64 +++ .../contracts/storage/PerpsAccount.sol | 8 - .../storage/PerpsMarketConfiguration.sol | 3 +- .../integration/Market/CreateMarket.test.ts | 2 + .../Orders/OffchainAsyncOrder.cancel.test.ts | 3 +- .../Orders/OffchainAsyncOrder.commit.test.ts | 38 +- .../Orders/OffchainAsyncOrder.fees.test.ts | 24 +- .../Orders/OffchainAsyncOrder.pending.test.ts | 31 +- .../Orders/OffchainAsyncOrder.price.test.ts | 5 +- .../OffchainAsyncOrder.referrer.test.ts | 400 ++++++++++++++++++ .../Orders/OffchainAsyncOrder.settle.test.ts | 46 +- .../test/integration/bootstrap/bootstrap.ts | 5 +- .../test/integration/helpers/openPosition.ts | 4 +- .../test/integration/helpers/settleHelper.ts | 7 +- .../interfaces/IMarketConfigurationModule.sol | 2 +- .../modules/AsyncOrderSettlementModule.sol | 2 +- 27 files changed, 841 insertions(+), 326 deletions(-) create mode 100644 markets/perps-market/contracts/interfaces/external/IFeeCollector.sol create mode 100644 markets/perps-market/contracts/mocks/FeeCollectorMock.sol create mode 100644 markets/perps-market/test/integration/Orders/OffchainAsyncOrder.referrer.test.ts diff --git a/markets/perps-market/cannonfile.test.toml b/markets/perps-market/cannonfile.test.toml index 6b8dab8bd6..f080434a42 100644 --- a/markets/perps-market/cannonfile.test.toml +++ b/markets/perps-market/cannonfile.test.toml @@ -161,3 +161,6 @@ depends = ['invoke.upgrade_proxy'] [contract.MockPyth] artifact = "contracts/mocks/MockPyth.sol:MockPyth" args = [100, 1] + +[contract.FeeCollectorMock] +artifact = "contracts/mocks/FeeCollectorMock.sol:FeeCollectorMock" diff --git a/markets/perps-market/contracts/interfaces/IAsyncOrderModule.sol b/markets/perps-market/contracts/interfaces/IAsyncOrderModule.sol index 9d711041ff..3e572bb14b 100644 --- a/markets/perps-market/contracts/interfaces/IAsyncOrderModule.sol +++ b/markets/perps-market/contracts/interfaces/IAsyncOrderModule.sol @@ -32,21 +32,6 @@ interface IAsyncOrderModule { address sender ); - /** - * @notice Gets fired when a new order is canceled. - * @param marketId Id of the market used for the trade. - * @param accountId Id of the account used for the trade. - * @param acceptablePrice maximum or minimum, depending on the sizeDelta direction, accepted price to settle the order, set by the user. - * @param settlementTime Time at which the order can be settled. - */ - - event OrderCanceled( - uint128 indexed marketId, - uint128 indexed accountId, - uint256 settlementTime, - uint256 acceptablePrice - ); - /** * @notice Commit an async order via this function * @param commitment Order commitment data (see AsyncOrder.OrderCommitmentRequest struct). @@ -57,23 +42,12 @@ interface IAsyncOrderModule { AsyncOrder.OrderCommitmentRequest memory commitment ) external returns (AsyncOrder.Data memory retOrder, uint fees); - /** - * @notice Cancel an expired order via this function - * @param marketId Id of the market used for the trade. - * @param accountId Id of the account used for the trade. - */ - function cancelOrder(uint128 marketId, uint128 accountId) external; - /** * @notice Get async order claim details * @param accountId id of the account. - * @param marketId Id of the market used for the trade. * @return order async order claim details (see AsyncOrder.Data struct). */ - function getOrder( - uint128 marketId, - uint128 accountId - ) external returns (AsyncOrder.Data memory order); + function getOrder(uint128 accountId) external returns (AsyncOrder.Data memory order); /** * @notice Simulates what the order fee would be for the given market with the specified size. diff --git a/markets/perps-market/contracts/interfaces/IAsyncOrderSettlementModule.sol b/markets/perps-market/contracts/interfaces/IAsyncOrderSettlementModule.sol index 447f59ff32..52907feb08 100644 --- a/markets/perps-market/contracts/interfaces/IAsyncOrderSettlementModule.sol +++ b/markets/perps-market/contracts/interfaces/IAsyncOrderSettlementModule.sol @@ -1,7 +1,8 @@ //SPDX-License-Identifier: MIT pragma solidity >=0.8.11 <0.9.0; import {SettlementStrategy} from "../storage/SettlementStrategy.sol"; -import {PerpsMarketFactory} from "../storage/PerpsMarketFactory.sol"; +import {Position} from "../storage/Position.sol"; +import {PerpsMarket} from "../storage/PerpsMarket.sol"; interface IAsyncOrderSettlementModule { /** @@ -26,7 +27,9 @@ interface IAsyncOrderSettlementModule { * @param fillPrice Price at which the order was settled. * @param sizeDelta Size delta from order. * @param newSize New size of the position after settlement. - * @param collectedFees Amount of fees collected by the protocol. + * @param totalFees Amount of fees collected by the protocol. + * @param referralFees Amount of fees collected by the referrer. + * @param collectedFees Amount of fees collected by fee collector. * @param settlementReward Amount of fees collected by the settler. * @param trackingCode Optional code for integrator tracking purposes. * @param settler address of the settler of the order. @@ -38,6 +41,8 @@ interface IAsyncOrderSettlementModule { int256 pnl, int128 sizeDelta, int128 newSize, + uint256 totalFees, + uint256 referralFees, uint256 collectedFees, uint256 settlementReward, bytes32 indexed trackingCode, @@ -54,15 +59,19 @@ interface IAsyncOrderSettlementModule { uint256 pnlUint; uint256 amountToDeduct; uint256 settlementReward; - PerpsMarketFactory.Data factory; + uint256 fillPrice; + uint256 totalFees; + uint256 referralFees; + uint256 feeCollectorFees; + Position.Data newPosition; + PerpsMarket.MarketUpdateData updateData; } /** * @notice Settles an offchain order. It's expected to revert with the OffchainLookup error with the data needed to perform the offchain lookup. - * @param marketId Id of the market used for the trade. * @param accountId Id of the account used for the trade. */ - function settle(uint128 marketId, uint128 accountId) external view; + function settle(uint128 accountId) external view; /** * @notice Settles an offchain order using the offchain retrieved data from pyth. diff --git a/markets/perps-market/contracts/interfaces/IGlobalPerpsMarketModule.sol b/markets/perps-market/contracts/interfaces/IGlobalPerpsMarketModule.sol index fb2f190d9d..924c500125 100644 --- a/markets/perps-market/contracts/interfaces/IGlobalPerpsMarketModule.sol +++ b/markets/perps-market/contracts/interfaces/IGlobalPerpsMarketModule.sol @@ -28,6 +28,29 @@ interface IGlobalPerpsMarketModule { uint256 indexed maxLiquidationRewardUsd ); + /** + * @notice emitted when custom fee collector is set + * @param feeCollector the address of the fee collector to set. + */ + event FeeCollectorSet(address feeCollector); + + /** + * @notice Emitted when the share percentage for a referrer address has been updated. + * @param referrer The address of the referrer + * @param shareRatioD18 The new share ratio for the referrer + */ + event ReferrerShareUpdated(address referrer, uint256 shareRatioD18); + + /** + * @notice Thrown when the fee collector does not implement the IFeeCollector interface + */ + error InvalidFeeCollectorInterface(address invalidFeeCollector); + + /** + * @notice Thrown when a referrer share gets set to larger than 100% + */ + error InvalidReferrerShareRatio(uint256 shareRatioD18); + /** * @notice Sets the max collateral amount for a specific synth market. * @param synthMarketId Synth market id, 0 for snxUSD. @@ -81,4 +104,31 @@ interface IGlobalPerpsMarketModule { * @return totalCollateralValue value of all collateral */ function totalGlobalCollateralValue() external view returns (uint256 totalCollateralValue); + + /** + * @notice Sets the fee collector contract. + * @dev must conform to the IFeeCollector interface + * @param feeCollector address of the fee collector contract + */ + function setFeeCollector(address feeCollector) external; + + /** + * @notice Gets the configured feeCollector contract + * @return feeCollector address of the fee collector contract + */ + function getFeeCollector() external view returns (address feeCollector); + + /** + * @notice Update the referral share percentage for a referrer + * @param referrer The address of the referrer + * @param shareRatioD18 The new share percentage for the referrer + */ + function updateReferrerShare(address referrer, uint256 shareRatioD18) external; + + /** + * @notice get the referral share percentage for the specified referrer + * @param referrer The address of the referrer + * @return shareRatioD18 The configured share percentage for the referrer + */ + function getReferrerShare(address referrer) external returns (uint256 shareRatioD18); } diff --git a/markets/perps-market/contracts/interfaces/external/IFeeCollector.sol b/markets/perps-market/contracts/interfaces/external/IFeeCollector.sol new file mode 100644 index 0000000000..28fdd2120d --- /dev/null +++ b/markets/perps-market/contracts/interfaces/external/IFeeCollector.sol @@ -0,0 +1,20 @@ +//SPDX-License-Identifier: MIT +pragma solidity >=0.8.11 <0.9.0; + +import "@synthetixio/core-contracts/contracts/interfaces/IERC165.sol"; + +interface IFeeCollector is IERC165 { + /** + * @notice .This function is called by the spot market proxy to get the fee amount to be collected. + * @dev .The quoted fee amount is then transferred directly to the fee collector. + * @param marketId .synth market id value + * @param feeAmount .max fee amount that can be collected + * @param transactor .the trader the fee was collected from + * @return feeAmountToCollect .quoted fee amount + */ + function quoteFees( + uint128 marketId, + uint256 feeAmount, + address transactor + ) external returns (uint256 feeAmountToCollect); +} diff --git a/markets/perps-market/contracts/mocks/FeeCollectorMock.sol b/markets/perps-market/contracts/mocks/FeeCollectorMock.sol new file mode 100644 index 0000000000..1fef86641e --- /dev/null +++ b/markets/perps-market/contracts/mocks/FeeCollectorMock.sol @@ -0,0 +1,34 @@ +//SPDX-License-Identifier: MIT +pragma solidity >=0.8.11 <0.9.0; + +import "@synthetixio/core-modules/contracts/interfaces/ITokenModule.sol"; +import "../interfaces/external/IFeeCollector.sol"; + +contract FeeCollectorMock is IFeeCollector { + uint feeRatioD18; + + function mockSetFeeRatio(uint _feeRatio) external { + feeRatioD18 = _feeRatio; + } + + // solc-ignore-next-line func-mutability + function quoteFees( + uint128 marketId, + uint256 feeAmount, + address sender + ) external override returns (uint256) { + // mention the variables in the block to prevent unused local variable warning + marketId; + sender; + + return (feeAmount * feeRatioD18) / 1e18; + } + + function supportsInterface( + bytes4 interfaceId + ) public view virtual override(IERC165) returns (bool) { + return + interfaceId == type(IFeeCollector).interfaceId || + interfaceId == this.supportsInterface.selector; + } +} diff --git a/markets/perps-market/contracts/modules/AsyncOrderModule.sol b/markets/perps-market/contracts/modules/AsyncOrderModule.sol index ded39bcec4..0b343c53aa 100644 --- a/markets/perps-market/contracts/modules/AsyncOrderModule.sol +++ b/markets/perps-market/contracts/modules/AsyncOrderModule.sol @@ -58,32 +58,23 @@ contract AsyncOrderModule is IAsyncOrderModule { GlobalPerpsMarket.load().checkLiquidation(commitment.accountId); - AsyncOrder.Data storage order = AsyncOrder.createValid( - commitment.accountId, - commitment.marketId - ); - SettlementStrategy.Data storage strategy = PerpsMarketConfiguration - .load(commitment.marketId) - .loadValidSettlementStrategy(commitment.settlementStrategyId); + .loadValidSettlementStrategy(commitment.marketId, commitment.settlementStrategyId); - uint256 settlementTime = block.timestamp + strategy.settlementDelay; - order.update(commitment, settlementTime); - - (, uint feesAccrued, , ) = order.validateOrder( + AsyncOrder.Data storage order = AsyncOrder.createValid(commitment, strategy); + (, uint feesAccrued, , ) = order.validateRequest( strategy, PerpsPrice.getCurrentPrice(commitment.marketId) ); - // TODO include fees in event emit OrderCommitted( commitment.marketId, commitment.accountId, strategy.strategyType, commitment.sizeDelta, commitment.acceptablePrice, - settlementTime, - settlementTime + strategy.settlementWindowDuration, + order.settlementTime, + order.settlementTime + strategy.settlementWindowDuration, commitment.trackingCode, msg.sender ); @@ -94,30 +85,11 @@ contract AsyncOrderModule is IAsyncOrderModule { /** * @inheritdoc IAsyncOrderModule */ + // solc-ignore-next-line func-mutability function getOrder( - uint128 marketId, uint128 accountId ) external view override returns (AsyncOrder.Data memory order) { order = AsyncOrder.load(accountId); - if (order.marketId != marketId) { - // return emtpy order if marketId does not match - order = AsyncOrder.Data(0, 0, 0, 0, 0, 0, 0); - } - } - - /** - * @inheritdoc IAsyncOrderModule - */ - function cancelOrder(uint128 marketId, uint128 accountId) external override { - AsyncOrder.Data storage order = AsyncOrder.loadValid(accountId, marketId); - - SettlementStrategy.Data storage settlementStrategy = PerpsMarketConfiguration - .load(marketId) - .settlementStrategies[order.settlementStrategyId]; - order.checkCancellationEligibility(settlementStrategy); - order.reset(); - - emit OrderCanceled(marketId, accountId, order.settlementTime, order.acceptablePrice); } /** diff --git a/markets/perps-market/contracts/modules/AsyncOrderSettlementModule.sol b/markets/perps-market/contracts/modules/AsyncOrderSettlementModule.sol index c1216a73d9..6d773086fe 100644 --- a/markets/perps-market/contracts/modules/AsyncOrderSettlementModule.sol +++ b/markets/perps-market/contracts/modules/AsyncOrderSettlementModule.sol @@ -18,6 +18,7 @@ import {GlobalPerpsMarket} from "../storage/GlobalPerpsMarket.sol"; import {PerpsMarketConfiguration} from "../storage/PerpsMarketConfiguration.sol"; import {SettlementStrategy} from "../storage/SettlementStrategy.sol"; import {PerpsMarketFactory} from "../storage/PerpsMarketFactory.sol"; +import {GlobalPerpsMarketConfiguration} from "../storage/GlobalPerpsMarketConfiguration.sol"; import {IMarketEvents} from "../interfaces/IMarketEvents.sol"; contract AsyncOrderSettlementModule is IAsyncOrderSettlementModule, IMarketEvents { @@ -31,6 +32,7 @@ contract AsyncOrderSettlementModule is IAsyncOrderSettlementModule, IMarketEvent using SettlementStrategy for SettlementStrategy.Data; using PerpsMarketFactory for PerpsMarketFactory.Data; using GlobalPerpsMarket for GlobalPerpsMarket.Data; + using GlobalPerpsMarketConfiguration for GlobalPerpsMarketConfiguration.Data; using PerpsMarketConfiguration for PerpsMarketConfiguration.Data; using Position for Position.Data; using SafeCastU256 for uint256; @@ -41,12 +43,12 @@ contract AsyncOrderSettlementModule is IAsyncOrderSettlementModule, IMarketEvent /** * @inheritdoc IAsyncOrderSettlementModule */ - function settle(uint128 marketId, uint128 accountId) external view { + function settle(uint128 accountId) external view { GlobalPerpsMarket.load().checkLiquidation(accountId); ( AsyncOrder.Data storage order, SettlementStrategy.Data storage settlementStrategy - ) = _performOrderValidityChecks(marketId, accountId); + ) = AsyncOrder.loadValid(accountId); _settleOffchain(order, settlementStrategy); } @@ -55,11 +57,11 @@ contract AsyncOrderSettlementModule is IAsyncOrderSettlementModule, IMarketEvent * @inheritdoc IAsyncOrderSettlementModule */ function settlePythOrder(bytes calldata result, bytes calldata extraData) external payable { - (uint128 marketId, uint128 asyncOrderId) = abi.decode(extraData, (uint128, uint128)); + uint128 accountId = abi.decode(extraData, (uint128)); ( AsyncOrder.Data storage order, SettlementStrategy.Data storage settlementStrategy - ) = _performOrderValidityChecks(marketId, asyncOrderId); + ) = AsyncOrder.loadValid(accountId); bytes32[] memory priceIds = new bytes32[](1); priceIds[0] = settlementStrategy.feedId; @@ -79,7 +81,10 @@ contract AsyncOrderSettlementModule is IAsyncOrderSettlementModule, IMarketEvent IPythVerifier.PriceFeed memory pythData = priceFeeds[0]; uint offchainPrice = _getScaledPrice(pythData.price.price, pythData.price.expo).toUint(); - settlementStrategy.checkPriceDeviation(offchainPrice, PerpsPrice.getCurrentPrice(marketId)); + settlementStrategy.checkPriceDeviation( + offchainPrice, + PerpsPrice.getCurrentPrice(order.request.marketId) + ); _settleOrder(offchainPrice, order, settlementStrategy); } @@ -107,7 +112,7 @@ contract AsyncOrderSettlementModule is IAsyncOrderSettlementModule, IMarketEvent urls, abi.encodePacked(settlementStrategy.feedId, _getTimeInBytes(asyncOrder.settlementTime)), selector, - abi.encode(asyncOrder.marketId, asyncOrder.accountId) // extraData that gets sent to callback for validation + abi.encode(asyncOrder.request.accountId) // extraData that gets sent to callback for validation ); } @@ -120,27 +125,24 @@ contract AsyncOrderSettlementModule is IAsyncOrderSettlementModule, IMarketEvent SettlementStrategy.Data storage settlementStrategy ) private { SettleOrderRuntime memory runtime; - runtime.accountId = asyncOrder.accountId; - runtime.marketId = asyncOrder.marketId; + runtime.accountId = asyncOrder.request.accountId; + runtime.marketId = asyncOrder.request.marketId; // check if account is flagged GlobalPerpsMarket.load().checkLiquidation(runtime.accountId); - ( - Position.Data memory newPosition, - uint totalFees, - uint fillPrice, - Position.Data storage oldPosition - ) = asyncOrder.validateOrder(settlementStrategy, price); + Position.Data storage oldPosition; + (runtime.newPosition, runtime.totalFees, runtime.fillPrice, oldPosition) = asyncOrder + .validateRequest(settlementStrategy, price); - runtime.amountToDeduct += totalFees; + runtime.amountToDeduct += runtime.totalFees; - runtime.newPositionSize = newPosition.size; - runtime.sizeDelta = asyncOrder.sizeDelta; + runtime.newPositionSize = runtime.newPosition.size; + runtime.sizeDelta = asyncOrder.request.sizeDelta; - runtime.factory = PerpsMarketFactory.load(); + PerpsMarketFactory.Data storage factory = PerpsMarketFactory.load(); PerpsAccount.Data storage perpsAccount = PerpsAccount.load(runtime.accountId); // use fill price to calculate realized pnl - (runtime.pnl, , , , ) = oldPosition.getPnl(fillPrice); + (runtime.pnl, , , , ) = oldPosition.getPnl(runtime.fillPrice); runtime.pnlUint = MathUtil.abs(runtime.pnl); if (runtime.pnl > 0) { @@ -150,19 +152,20 @@ contract AsyncOrderSettlementModule is IAsyncOrderSettlementModule, IMarketEvent } // after pnl is realized, update position - PerpsMarket.MarketUpdateData memory updateData = PerpsMarket - .loadValid(runtime.marketId) - .updatePositionData(runtime.accountId, newPosition); + runtime.updateData = PerpsMarket.loadValid(runtime.marketId).updatePositionData( + runtime.accountId, + runtime.newPosition + ); perpsAccount.updateOpenPositions(runtime.marketId, runtime.newPositionSize); emit MarketUpdated( - updateData.marketId, + runtime.updateData.marketId, price, - updateData.skew, - updateData.size, + runtime.updateData.skew, + runtime.updateData.size, runtime.sizeDelta, - updateData.currentFundingRate, - updateData.currentFundingVelocity + runtime.updateData.currentFundingRate, + runtime.updateData.currentFundingVelocity ); // since margin is deposited, as long as the owed collateral is deducted @@ -174,13 +177,17 @@ contract AsyncOrderSettlementModule is IAsyncOrderSettlementModule, IMarketEvent if (runtime.settlementReward > 0) { // pay keeper - runtime.factory.synthetix.withdrawMarketUsd( - runtime.factory.perpsMarketId, - msg.sender, - runtime.settlementReward - ); + factory.withdrawMarketUsd(msg.sender, runtime.settlementReward); } + (runtime.referralFees, runtime.feeCollectorFees) = GlobalPerpsMarketConfiguration + .load() + .collectFees( + runtime.totalFees - runtime.settlementReward, // totalFees includes settlement reward so we remove it + asyncOrder.request.referrer, + factory + ); + // trader can now commit a new order asyncOrder.reset(); @@ -188,35 +195,19 @@ contract AsyncOrderSettlementModule is IAsyncOrderSettlementModule, IMarketEvent emit OrderSettled( runtime.marketId, runtime.accountId, - fillPrice, + runtime.fillPrice, runtime.pnl, runtime.sizeDelta, runtime.newPositionSize, - totalFees, + runtime.totalFees, + runtime.referralFees, + runtime.feeCollectorFees, runtime.settlementReward, - asyncOrder.trackingCode, + asyncOrder.request.trackingCode, msg.sender ); } - /** - * @dev performs the order validity checks (existance and timing). - */ - function _performOrderValidityChecks( - uint128 marketId, - uint128 accountId - ) private view returns (AsyncOrder.Data storage, SettlementStrategy.Data storage) { - AsyncOrder.Data storage order = AsyncOrder.loadValid(accountId, marketId); - - SettlementStrategy.Data storage settlementStrategy = PerpsMarketConfiguration - .load(marketId) - .settlementStrategies[order.settlementStrategyId]; - - order.checkWithinSettlementWindow(settlementStrategy); - - return (order, settlementStrategy); - } - /** * @dev converts the settlement time into bytes8. */ diff --git a/markets/perps-market/contracts/modules/GlobalPerpsMarketModule.sol b/markets/perps-market/contracts/modules/GlobalPerpsMarketModule.sol index 26528b9ae8..58933b0740 100644 --- a/markets/perps-market/contracts/modules/GlobalPerpsMarketModule.sol +++ b/markets/perps-market/contracts/modules/GlobalPerpsMarketModule.sol @@ -1,6 +1,9 @@ //SPDX-License-Identifier: MIT pragma solidity >=0.8.11 <0.9.0; +import {DecimalMath} from "@synthetixio/core-contracts/contracts/utils/DecimalMath.sol"; +import {ERC165Helper} from "@synthetixio/core-contracts/contracts/utils/ERC165Helper.sol"; +import {IFeeCollector} from "../interfaces/external/IFeeCollector.sol"; import {GlobalPerpsMarketConfiguration} from "../storage/GlobalPerpsMarketConfiguration.sol"; import {GlobalPerpsMarket} from "../storage/GlobalPerpsMarket.sol"; import {IGlobalPerpsMarketModule} from "../interfaces/IGlobalPerpsMarketModule.sol"; @@ -95,4 +98,52 @@ contract GlobalPerpsMarketModule is IGlobalPerpsMarketModule { { return GlobalPerpsMarket.load().totalCollateralValue(); } + + /** + * @inheritdoc IGlobalPerpsMarketModule + */ + function setFeeCollector(address feeCollector) external override { + OwnableStorage.onlyOwner(); + if (feeCollector != address(0)) { + if ( + !ERC165Helper.safeSupportsInterface(feeCollector, type(IFeeCollector).interfaceId) + ) { + revert InvalidFeeCollectorInterface(feeCollector); + } + } + + GlobalPerpsMarketConfiguration.load().feeCollector = IFeeCollector(feeCollector); + emit FeeCollectorSet(feeCollector); + } + + /** + * @inheritdoc IGlobalPerpsMarketModule + */ + function getFeeCollector() external view override returns (address feeCollector) { + return address(GlobalPerpsMarketConfiguration.load().feeCollector); + } + + /** + * @inheritdoc IGlobalPerpsMarketModule + */ + function updateReferrerShare(address referrer, uint256 shareRatioD18) external override { + OwnableStorage.onlyOwner(); + + if (shareRatioD18 > DecimalMath.UNIT) { + revert InvalidReferrerShareRatio(shareRatioD18); + } + + GlobalPerpsMarketConfiguration.load().referrerShare[referrer] = shareRatioD18; + + emit ReferrerShareUpdated(referrer, shareRatioD18); + } + + /** + * @inheritdoc IGlobalPerpsMarketModule + */ + function getReferrerShare( + address referrer + ) external view override returns (uint256 shareRatioD18) { + return GlobalPerpsMarketConfiguration.load().referrerShare[referrer]; + } } diff --git a/markets/perps-market/contracts/modules/PerpsAccountModule.sol b/markets/perps-market/contracts/modules/PerpsAccountModule.sol index 01d08febf2..767386d231 100644 --- a/markets/perps-market/contracts/modules/PerpsAccountModule.sol +++ b/markets/perps-market/contracts/modules/PerpsAccountModule.sol @@ -53,7 +53,7 @@ contract PerpsAccountModule is IPerpsAccountModule { PerpsAccount.Data storage account = PerpsAccount.create(accountId); uint128 perpsMarketId = PerpsMarketFactory.load().perpsMarketId; - account.checkPendingOrder(); + AsyncOrder.checkPendingOrder(account.id); if (amountDelta > 0) { _depositMargin(perpsMarketFactory, perpsMarketId, synthMarketId, amountDelta.toUint()); diff --git a/markets/perps-market/contracts/storage/AsyncOrder.sol b/markets/perps-market/contracts/storage/AsyncOrder.sol index 58f8adabe2..0fb6dd1e95 100644 --- a/markets/perps-market/contracts/storage/AsyncOrder.sol +++ b/markets/perps-market/contracts/storage/AsyncOrder.sol @@ -28,6 +28,11 @@ library AsyncOrder { using PerpsAccount for PerpsAccount.Data; using Position for Position.Data; + /** + * @notice Thrown when settlement window is not open yet. + */ + error SettlementWindowNotOpen(uint256 timestamp, uint256 settlementTime); + /** * @notice Thrown when attempting to settle an expired order. */ @@ -57,15 +62,10 @@ library AsyncOrder { */ error AcceptablePriceExceeded(uint256 acceptablePrice, uint256 fillPrice); - /** - * @notice Gets thrown when commit order is called when a pending order already exists. - */ - error OrderAlreadyCommitted(uint128 marketId, uint128 accountId); - /** * @notice Gets thrown when pending orders exist and attempts to modify collateral. */ - error PendingOrderExist(); + error PendingOrderExists(); /** * @notice Thrown when commiting an order with sizeDelta is zero. @@ -79,34 +79,14 @@ library AsyncOrder { error InsufficientMargin(int availableMargin, uint minMargin); struct Data { - /** - * @dev Order account id. - */ - uint128 accountId; - /** - * @dev Order market id. - */ - uint128 marketId; - /** - * @dev Order size delta (of asset units expressed in decimal 18 digits). It can be positive or negative. - */ - int128 sizeDelta; - /** - * @dev Settlement strategy used for the order. - */ - uint128 settlementStrategyId; /** * @dev Time at which the Settlement time is open. */ uint256 settlementTime; /** - * @dev Acceptable price set at submission. Longs will not be filled above this price, and shorts will not be filled below it. - */ - uint256 acceptablePrice; - /** - * @dev An optional code provided by frontends to assist with tracking the source of volume and fees. + * @dev Order request details. */ - bytes32 trackingCode; + OrderCommitmentRequest request; } struct OrderCommitmentRequest { @@ -134,6 +114,10 @@ library AsyncOrder { * @dev An optional code provided by frontends to assist with tracking the source of volume and fees. */ bytes32 trackingCode; + /** + * @dev Referrer address to send the referrer fees to. + */ + address referrer; } /** @@ -148,17 +132,21 @@ library AsyncOrder { } /** - * @dev Reverts if the order does not belongs to the market or not exists. Otherwise, returns the order. - * @dev non-existent order is considered an order with sizeDelta == 0. + * @dev Reverts if order was not committed by checking the sizeDelta. + * @dev Reverts if order is not in the settlement window. */ function loadValid( - uint128 accountId, - uint128 marketId - ) internal view returns (Data storage order) { + uint128 accountId + ) internal view returns (Data storage order, SettlementStrategy.Data storage strategy) { order = load(accountId); - if (order.marketId != marketId || order.sizeDelta == 0) { + if (order.request.sizeDelta == 0) { revert OrderNotValid(); } + + strategy = PerpsMarketConfiguration.load(order.request.marketId).settlementStrategies[ + order.request.settlementStrategyId + ]; + checkWithinSettlementWindow(order, strategy); } /** @@ -166,41 +154,41 @@ library AsyncOrder { * @dev non-existent order is considered an order with sizeDelta == 0. */ function createValid( - uint128 accountId, - uint128 marketId - ) internal view returns (Data storage order) { - order = load(accountId); - if (order.sizeDelta != 0 && order.marketId == marketId) { - revert OrderAlreadyCommitted(marketId, accountId); - } + OrderCommitmentRequest memory newRequest, + SettlementStrategy.Data storage strategy + ) internal returns (Data storage order) { + order = checkPendingOrder(newRequest.accountId); - if (order.sizeDelta != 0) { - revert PendingOrderExist(); - } + order.settlementTime = block.timestamp + strategy.settlementDelay; + order.request = newRequest; } - function update( - Data storage self, - OrderCommitmentRequest memory commitment, - uint256 settlementTime - ) internal { - self.sizeDelta = commitment.sizeDelta; - self.settlementStrategyId = commitment.settlementStrategyId; - self.settlementTime = settlementTime; - self.acceptablePrice = commitment.acceptablePrice; - self.trackingCode = commitment.trackingCode; - self.marketId = commitment.marketId; - self.accountId = commitment.accountId; + /** + * @dev Reverts if there is a pending order. + * @dev A pending order is one that has a sizeDelta or isn't expired yet. + */ + function checkPendingOrder(uint128 accountId) internal view returns (Data storage order) { + order = load(accountId); + + if (order.request.sizeDelta != 0) { + SettlementStrategy.Data storage strategy = PerpsMarketConfiguration + .load(order.request.marketId) + .settlementStrategies[order.request.settlementStrategyId]; + + if (!expired(order, strategy)) { + revert PendingOrderExists(); + } + } } /** * @notice Resets the order. - * @dev This function is called after the order is settled or cancelled. + * @dev This function is called after the order is settled. * @dev Just setting the sizeDelta to 0 is enough, since is the value checked to identify an active order at settlement time. * @dev The rest of the fields will be updated on the next commitment. Not doing it here is more gas efficient. */ function reset(Data storage self) internal { - self.sizeDelta = 0; + self.request.sizeDelta = 0; } /** @@ -214,7 +202,12 @@ library AsyncOrder { ) internal view { uint settlementExpiration = self.settlementTime + settlementStrategy.settlementWindowDuration; - if (block.timestamp < self.settlementTime || block.timestamp > settlementExpiration) { + + if (block.timestamp < self.settlementTime) { + revert SettlementWindowNotOpen(block.timestamp, self.settlementTime); + } + + if (expired(self, settlementStrategy)) { revert SettlementWindowExpired( block.timestamp, self.settlementTime, @@ -224,38 +217,24 @@ library AsyncOrder { } /** - * @notice Checks if the order can be cancelled. - * @dev Reverts if block.timestamp is < settlementTime + settlementWindowDuration - * @dev it means it didn't expire yet. + * @notice Returns if order is expired or not */ - function checkCancellationEligibility( + function expired( Data storage self, SettlementStrategy.Data storage settlementStrategy - ) internal view { + ) internal view returns (bool) { uint settlementExpiration = self.settlementTime + settlementStrategy.settlementWindowDuration; - if (block.timestamp < settlementExpiration) { - revert SettlementWindowNotExpired( - block.timestamp, - self.settlementTime, - settlementExpiration - ); - } - } - - /** - * @notice Checks if the storage order is valid (exists), and reverts otherwise - */ - function checkValidity(Data storage self) internal view { - if (self.sizeDelta == 0) { - revert OrderNotValid(); - } + return block.timestamp > settlementExpiration; } /** * @dev Struct used internally in validateOrder() to prevent stack too deep error. */ struct SimulateDataRuntime { + int128 sizeDelta; + uint128 accountId; + uint128 marketId; uint fillPrice; uint orderFees; uint availableMargin; @@ -271,7 +250,7 @@ library AsyncOrder { } /** - * @notice Checks if the order can be settled. + * @notice Checks if the order request can be settled. * @dev it recomputes market funding rate, calculates fill price and fees for the order * @dev and with that data it checks that: * @dev - the account is eligible for liquidation @@ -281,51 +260,54 @@ library AsyncOrder { * @dev - the account has enough margin to not be liquidable immediately after the order is settled * @dev if the order can be executed, it returns (newPosition, orderFees, fillPrice, oldPosition) */ - function validateOrder( + function validateRequest( Data storage order, SettlementStrategy.Data storage strategy, uint256 orderPrice ) internal returns (Position.Data memory, uint, uint, Position.Data storage oldPosition) { - if (order.sizeDelta == 0) { + SimulateDataRuntime memory runtime; + runtime.sizeDelta = order.request.sizeDelta; + runtime.accountId = order.request.accountId; + runtime.marketId = order.request.marketId; + + if (runtime.sizeDelta == 0) { revert ZeroSizeOrder(); } - SimulateDataRuntime memory runtime; - - PerpsAccount.Data storage account = PerpsAccount.load(order.accountId); + PerpsAccount.Data storage account = PerpsAccount.load(runtime.accountId); bool isEligible; (isEligible, runtime.currentAvailableMargin, , runtime.requiredMaintenanceMargin) = account .isEligibleForLiquidation(); if (isEligible) { - revert PerpsAccount.AccountLiquidatable(order.accountId); + revert PerpsAccount.AccountLiquidatable(runtime.accountId); } - PerpsMarket.Data storage perpsMarketData = PerpsMarket.load(order.marketId); + PerpsMarket.Data storage perpsMarketData = PerpsMarket.load(runtime.marketId); perpsMarketData.recomputeFunding(orderPrice); PerpsMarketConfiguration.Data storage marketConfig = PerpsMarketConfiguration.load( - order.marketId + runtime.marketId ); runtime.fillPrice = calculateFillPrice( perpsMarketData.skew, marketConfig.skewScale, - order.sizeDelta, + runtime.sizeDelta, orderPrice ); if ( - (order.sizeDelta > 0 && runtime.fillPrice > order.acceptablePrice) || - (order.sizeDelta < 0 && runtime.fillPrice < order.acceptablePrice) + (runtime.sizeDelta > 0 && runtime.fillPrice > order.request.acceptablePrice) || + (runtime.sizeDelta < 0 && runtime.fillPrice < order.request.acceptablePrice) ) { - revert AcceptablePriceExceeded(runtime.fillPrice, order.acceptablePrice); + revert AcceptablePriceExceeded(runtime.fillPrice, order.request.acceptablePrice); } runtime.orderFees = calculateOrderFee( - order.sizeDelta, + runtime.sizeDelta, runtime.fillPrice, perpsMarketData.skew, marketConfig.orderFees @@ -336,16 +318,16 @@ library AsyncOrder { revert InsufficientMargin(runtime.currentAvailableMargin, runtime.orderFees); } - oldPosition = PerpsMarket.load(order.marketId).positions[order.accountId]; + oldPosition = PerpsMarket.load(runtime.marketId).positions[runtime.accountId]; PerpsMarket.validatePositionSize( perpsMarketData, marketConfig.maxMarketSize, oldPosition.size, - order.sizeDelta + runtime.sizeDelta ); - runtime.newPositionSize = oldPosition.size + order.sizeDelta; + runtime.newPositionSize = oldPosition.size + runtime.sizeDelta; (, , runtime.initialRequiredMargin, , ) = marketConfig.calculateRequiredMargins( runtime.newPositionSize, runtime.fillPrice @@ -366,13 +348,12 @@ library AsyncOrder { runtime.initialRequiredMargin - currentMarketMaintenanceMargin; - // TODO: create new errors for different scenarios instead of reusing InsufficientMargin if (runtime.currentAvailableMargin < runtime.totalRequiredMargin.toInt()) { revert InsufficientMargin(runtime.currentAvailableMargin, runtime.totalRequiredMargin); } runtime.newPosition = Position.Data({ - marketId: order.marketId, + marketId: runtime.marketId, latestInteractionPrice: runtime.fillPrice.to128(), latestInteractionFunding: perpsMarketData.lastFundingValue.to128(), size: runtime.newPositionSize diff --git a/markets/perps-market/contracts/storage/GlobalPerpsMarketConfiguration.sol b/markets/perps-market/contracts/storage/GlobalPerpsMarketConfiguration.sol index 12972e3037..8e2688fa47 100644 --- a/markets/perps-market/contracts/storage/GlobalPerpsMarketConfiguration.sol +++ b/markets/perps-market/contracts/storage/GlobalPerpsMarketConfiguration.sol @@ -1,16 +1,31 @@ //SPDX-License-Identifier: MIT pragma solidity >=0.8.11 <0.9.0; +import {DecimalMath} from "@synthetixio/core-contracts/contracts/utils/DecimalMath.sol"; import {MathUtil} from "../utils/MathUtil.sol"; +import {IFeeCollector} from "../interfaces/external/IFeeCollector.sol"; +import {PerpsMarketFactory} from "./PerpsMarketFactory.sol"; /** * @title This library contains all global perps market configuration data */ library GlobalPerpsMarketConfiguration { + using DecimalMath for uint256; + using PerpsMarketFactory for PerpsMarketFactory.Data; + bytes32 private constant _SLOT_GLOBAL_PERPS_MARKET_CONFIGURATION = keccak256(abi.encode("io.synthetix.perps-market.GlobalPerpsMarketConfiguration")); struct Data { + /** + * @dev fee collector contract + * @dev portion or all of the order fees are sent to fee collector contract based on quote. + */ + IFeeCollector feeCollector; + /** + * @dev Percentage share of fees for each referrer address + */ + mapping(address => uint256) referrerShare; /** * @dev mapping of configured synthMarketId to max collateral amount. * @dev USD token synth market id = 0 @@ -50,4 +65,53 @@ library GlobalPerpsMarketConfiguration { self.maxLiquidationRewardUsd ); } + + function collectFees( + Data storage self, + uint256 orderFees, + address referrer, + PerpsMarketFactory.Data storage factory + ) internal returns (uint256 referralFees, uint256 feeCollectorFees) { + referralFees = _collectReferrerFees(self, orderFees, referrer, factory); + uint256 remainingFees = orderFees - referralFees; + + if (remainingFees == 0 || self.feeCollector == IFeeCollector(address(0))) { + return (referralFees, 0); + } + + uint256 feeCollectorQuote = self.feeCollector.quoteFees( + factory.perpsMarketId, + remainingFees, + msg.sender + ); + + if (feeCollectorQuote == 0) { + return (referralFees, 0); + } + + if (feeCollectorQuote > remainingFees) { + feeCollectorQuote = remainingFees; + } + + factory.withdrawMarketUsd(address(self.feeCollector), feeCollectorQuote); + + return (referralFees, feeCollectorQuote); + } + + function _collectReferrerFees( + Data storage self, + uint256 fees, + address referrer, + PerpsMarketFactory.Data storage factory + ) private returns (uint256 referralFeesSent) { + if (referrer == address(0)) { + return 0; + } + + uint256 referrerShareRatio = self.referrerShare[referrer]; + if (referrerShareRatio > 0) { + referralFeesSent = fees.mulDecimal(referrerShareRatio); + factory.withdrawMarketUsd(referrer, referralFeesSent); + } + } } diff --git a/markets/perps-market/contracts/storage/PerpsAccount.sol b/markets/perps-market/contracts/storage/PerpsAccount.sol index d49d72eee5..db73af9343 100644 --- a/markets/perps-market/contracts/storage/PerpsAccount.sol +++ b/markets/perps-market/contracts/storage/PerpsAccount.sol @@ -109,14 +109,6 @@ library PerpsAccount { } } - function checkPendingOrder(Data storage self) internal view { - // Check if there are pending orders - AsyncOrder.Data memory asyncOrder = AsyncOrder.load(self.id); - if (asyncOrder.sizeDelta != 0) { - revert AsyncOrder.PendingOrderExist(); - } - } - function updateCollateralAmount( Data storage self, uint128 synthMarketId, diff --git a/markets/perps-market/contracts/storage/PerpsMarketConfiguration.sol b/markets/perps-market/contracts/storage/PerpsMarketConfiguration.sol index 29b75c4d35..410dfbf723 100644 --- a/markets/perps-market/contracts/storage/PerpsMarketConfiguration.sol +++ b/markets/perps-market/contracts/storage/PerpsMarketConfiguration.sol @@ -111,9 +111,10 @@ library PerpsMarketConfiguration { * @notice given a strategy id, returns the entire settlement strategy struct */ function loadValidSettlementStrategy( - Data storage self, + uint128 marketId, uint128 settlementStrategyId ) internal view returns (SettlementStrategy.Data storage strategy) { + Data storage self = load(marketId); if (settlementStrategyId >= self.settlementStrategies.length) { revert InvalidSettlementStrategy(settlementStrategyId); } diff --git a/markets/perps-market/test/integration/Market/CreateMarket.test.ts b/markets/perps-market/test/integration/Market/CreateMarket.test.ts index c3313f247e..875be5e879 100644 --- a/markets/perps-market/test/integration/Market/CreateMarket.test.ts +++ b/markets/perps-market/test/integration/Market/CreateMarket.test.ts @@ -192,6 +192,7 @@ describe('Create Market test', () => { sizeDelta: bn(1), settlementStrategyId: 0, acceptablePrice: bn(1050), // 5% slippage + referrer: ethers.constants.AddressZero, trackingCode: ethers.constants.HashZero, }), 'PriceFeedNotSet' @@ -240,6 +241,7 @@ describe('Create Market test', () => { sizeDelta: bn(1), settlementStrategyId: 0, acceptablePrice: bn(1050), // 5% slippage + referrer: ethers.constants.AddressZero, trackingCode: ethers.constants.HashZero, }); }); diff --git a/markets/perps-market/test/integration/Orders/OffchainAsyncOrder.cancel.test.ts b/markets/perps-market/test/integration/Orders/OffchainAsyncOrder.cancel.test.ts index 6baff6a311..f2d7ad3004 100644 --- a/markets/perps-market/test/integration/Orders/OffchainAsyncOrder.cancel.test.ts +++ b/markets/perps-market/test/integration/Orders/OffchainAsyncOrder.cancel.test.ts @@ -6,7 +6,7 @@ import assertRevert from '@synthetixio/core-utils/utils/assertions/assert-revert import assertBn from '@synthetixio/core-utils/src/utils/assertions/assert-bignumber'; import assertEvent from '@synthetixio/core-utils/src/utils/assertions/assert-event'; -describe('Cancel Offchain Async Order test', () => { +describe.skip('Cancel Offchain Async Order test', () => { const { systems, perpsMarkets, provider, trader1 } = bootstrapMarkets({ synthMarkets: [], perpsMarkets: [ @@ -47,6 +47,7 @@ describe('Cancel Offchain Async Order test', () => { sizeDelta: bn(1), settlementStrategyId: 0, acceptablePrice: bn(1050), // 5% slippage + referrer: ethers.constants.AddressZero, trackingCode: ethers.constants.HashZero, }); await tx.wait(); diff --git a/markets/perps-market/test/integration/Orders/OffchainAsyncOrder.commit.test.ts b/markets/perps-market/test/integration/Orders/OffchainAsyncOrder.commit.test.ts index 821a0d50c3..79c97fda70 100644 --- a/markets/perps-market/test/integration/Orders/OffchainAsyncOrder.commit.test.ts +++ b/markets/perps-market/test/integration/Orders/OffchainAsyncOrder.commit.test.ts @@ -54,6 +54,7 @@ describe('Commit Offchain Async Order test', () => { sizeDelta: bn(1), settlementStrategyId: 0, acceptablePrice: bn(1050), // 5% slippage + referrer: ethers.constants.AddressZero, trackingCode: ethers.constants.HashZero, }), 'InvalidMarket("1337")' @@ -70,6 +71,7 @@ describe('Commit Offchain Async Order test', () => { sizeDelta: bn(1), settlementStrategyId: 0, acceptablePrice: bn(1050), // 5% slippage + referrer: ethers.constants.AddressZero, trackingCode: ethers.constants.HashZero, }), 'AccountNotFound("1337")' @@ -86,6 +88,7 @@ describe('Commit Offchain Async Order test', () => { sizeDelta: bn(1), settlementStrategyId: 0, acceptablePrice: bn(1050), // 5% slippage + referrer: ethers.constants.AddressZero, trackingCode: ethers.constants.HashZero, }), 'InsufficientMargin' @@ -102,6 +105,7 @@ describe('Commit Offchain Async Order test', () => { sizeDelta: bn(1), settlementStrategyId: 0, acceptablePrice: bn(1050), // 5% slippage + referrer: ethers.constants.AddressZero, trackingCode: ethers.constants.HashZero, }), `PermissionDenied("${2}", "${PERPS_COMMIT_ASYNC_ORDER_PERMISSION_NAME}", "${await keeper().getAddress()}")` @@ -179,6 +183,7 @@ describe('Commit Offchain Async Order test', () => { sizeDelta: bn(1), settlementStrategyId: 0, acceptablePrice: bn(1050), // 5% slippage + referrer: ethers.constants.AddressZero, trackingCode: ethers.constants.HashZero, }); startTime = await getTxTime(provider(), tx); @@ -197,14 +202,14 @@ describe('Commit Offchain Async Order test', () => { }); it('identifies the pending order', async () => { - const order = await systems().PerpsMarket.getOrder(ethMarketId, 2); - assertBn.equal(order.accountId, 2); - assertBn.equal(order.marketId, ethMarketId); - assertBn.equal(order.sizeDelta, bn(1)); - assertBn.equal(order.settlementStrategyId, 0); + const order = await systems().PerpsMarket.getOrder(2); + assertBn.equal(order.request.accountId, 2); + assertBn.equal(order.request.marketId, ethMarketId); + assertBn.equal(order.request.sizeDelta, bn(1)); + assertBn.equal(order.request.settlementStrategyId, 0); assertBn.equal(order.settlementTime, startTime + 5); - assertBn.equal(order.acceptablePrice, bn(1050)); - assert.equal(order.trackingCode, ethers.constants.HashZero); + assertBn.equal(order.request.acceptablePrice, bn(1050)); + assert.equal(order.request.trackingCode, ethers.constants.HashZero); }); it('reverts if attempt to commit another order for same account and market', async () => { @@ -217,9 +222,10 @@ describe('Commit Offchain Async Order test', () => { sizeDelta: bn(2), settlementStrategyId: 0, acceptablePrice: bn(1050), // 5% slippage + referrer: ethers.constants.AddressZero, trackingCode: ethers.constants.HashZero, }), - `OrderAlreadyCommitted("${ethMarketId}", "2")` + 'PendingOrderExists()' ); }); @@ -230,7 +236,6 @@ describe('Commit Offchain Async Order test', () => { await settleOrder({ systems, keeper: keeper(), - marketId: ethMarketId, accountId: 2, feedId: DEFAULT_SETTLEMENT_STRATEGY.feedId, settlementTime, @@ -255,6 +260,7 @@ describe('Commit Offchain Async Order test', () => { sizeDelta: bn(1), settlementStrategyId: 0, acceptablePrice: bn(1050), // 5% slippage + referrer: ethers.constants.AddressZero, trackingCode: ethers.constants.HashZero, }); startTime = await getTxTime(provider(), tx); @@ -273,14 +279,14 @@ describe('Commit Offchain Async Order test', () => { }); it('identifies the pending order', async () => { - const order = await systems().PerpsMarket.getOrder(ethMarketId, 2); - assertBn.equal(order.accountId, 2); - assertBn.equal(order.marketId, ethMarketId); - assertBn.equal(order.sizeDelta, bn(1)); - assertBn.equal(order.settlementStrategyId, 0); + const order = await systems().PerpsMarket.getOrder(2); + assertBn.equal(order.request.accountId, 2); + assertBn.equal(order.request.marketId, ethMarketId); + assertBn.equal(order.request.sizeDelta, bn(1)); + assertBn.equal(order.request.settlementStrategyId, 0); assertBn.equal(order.settlementTime, startTime + 5); - assertBn.equal(order.acceptablePrice, bn(1050)); - assert.equal(order.trackingCode, ethers.constants.HashZero); + assertBn.equal(order.request.acceptablePrice, bn(1050)); + assert.equal(order.request.trackingCode, ethers.constants.HashZero); }); }); }); diff --git a/markets/perps-market/test/integration/Orders/OffchainAsyncOrder.fees.test.ts b/markets/perps-market/test/integration/Orders/OffchainAsyncOrder.fees.test.ts index 97dc28a4fd..a5ef78bece 100644 --- a/markets/perps-market/test/integration/Orders/OffchainAsyncOrder.fees.test.ts +++ b/markets/perps-market/test/integration/Orders/OffchainAsyncOrder.fees.test.ts @@ -147,6 +147,7 @@ describe('Offchain Async Order test - fees', () => { sizeDelta, settlementStrategyId: 0, acceptablePrice: bn(1050), // 5% slippage + referrer: ethers.constants.AddressZero, trackingCode: ethers.constants.HashZero, }); @@ -169,28 +170,6 @@ describe('Offchain Async Order test - fees', () => { const restoreToKeeper = snapshotCheckpoint(provider); - describe('when canceling the order', () => { - before(restoreToKeeper); - - before('cancel the order', async () => { - await fastForwardTo( - startTime + - DEFAULT_SETTLEMENT_STRATEGY.settlementDelay + - DEFAULT_SETTLEMENT_STRATEGY.settlementWindowDuration + - 1, - provider() - ); - tx = await systems().PerpsMarket.cancelOrder(ethMarketId, 2); - }); - - it('validate no fees are paid on cancel', async () => { - const { traderBalance, keeperBalance } = await getBalances(); - - assertBn.equal(traderBalance, balancesBeforeLong.traderBalance); - assertBn.equal(keeperBalance, balancesBeforeLong.keeperBalance); - }); - }); - describe('when settling the order', () => { before(restoreToKeeper); @@ -200,7 +179,6 @@ describe('Offchain Async Order test - fees', () => { await settleOrder({ systems, keeper: keeper(), - marketId: ethMarketId, accountId: 2, feedId: DEFAULT_SETTLEMENT_STRATEGY.feedId, settlementTime, diff --git a/markets/perps-market/test/integration/Orders/OffchainAsyncOrder.pending.test.ts b/markets/perps-market/test/integration/Orders/OffchainAsyncOrder.pending.test.ts index b8ba36256e..05bb26ed44 100644 --- a/markets/perps-market/test/integration/Orders/OffchainAsyncOrder.pending.test.ts +++ b/markets/perps-market/test/integration/Orders/OffchainAsyncOrder.pending.test.ts @@ -60,6 +60,7 @@ describe('Offchain Async Order - Prevent updates with pending order test', () => sizeDelta: bn(1), settlementStrategyId: 0, acceptablePrice: bn(1050), // 5% slippage + referrer: ethers.constants.AddressZero, trackingCode: ethers.constants.HashZero, }); startTime = await getTxTime(provider(), tx); @@ -73,7 +74,7 @@ describe('Offchain Async Order - Prevent updates with pending order test', () => it('reverts if attempt to update collateral', async () => { await assertRevert( systems().PerpsMarket.connect(trader1()).modifyCollateral(2, 0, bn(10)), - 'PendingOrderExist()', + 'PendingOrderExists()', systems().PerpsMarket ); }); @@ -88,9 +89,10 @@ describe('Offchain Async Order - Prevent updates with pending order test', () => sizeDelta: bn(0.01), settlementStrategyId: 0, acceptablePrice: bn(10050), // 5% slippage + referrer: ethers.constants.AddressZero, trackingCode: ethers.constants.HashZero, }), - 'PendingOrderExist()', + 'PendingOrderExists()', systems().PerpsMarket ); }); @@ -105,7 +107,6 @@ describe('Offchain Async Order - Prevent updates with pending order test', () => await settleOrder({ systems, keeper: keeper(), - marketId: ethMarketId, accountId: 2, feedId: DEFAULT_SETTLEMENT_STRATEGY.feedId, settlementTime, @@ -131,20 +132,21 @@ describe('Offchain Async Order - Prevent updates with pending order test', () => sizeDelta: bn(1), settlementStrategyId: 0, acceptablePrice: bn(10050), // 5% slippage + referrer: ethers.constants.AddressZero, trackingCode: ethers.constants.HashZero, }); - const order = await systems().PerpsMarket.getOrder(btcMarketId, 2); - assertBn.equal(order.accountId, 2); - assertBn.equal(order.marketId, btcMarketId); - assertBn.equal(order.sizeDelta, bn(1)); + const order = await systems().PerpsMarket.getOrder(2); + assertBn.equal(order.request.accountId, 2); + assertBn.equal(order.request.marketId, btcMarketId); + assertBn.equal(order.request.sizeDelta, bn(1)); }); }); - describe('after cancel the pending order', () => { + describe('after expiration of current order', () => { before(restoreToCommit); - before('cancel the order', async () => { + before(async () => { await fastForwardTo( startTime + DEFAULT_SETTLEMENT_STRATEGY.settlementDelay + @@ -152,7 +154,7 @@ describe('Offchain Async Order - Prevent updates with pending order test', () => 1, provider() ); - await systems().PerpsMarket.cancelOrder(ethMarketId, 2); + // await systems().PerpsMarket.cancelOrder(ethMarketId, 2); }); it('can update the collateral', async () => { @@ -173,13 +175,14 @@ describe('Offchain Async Order - Prevent updates with pending order test', () => sizeDelta: bn(1), settlementStrategyId: 0, acceptablePrice: bn(10050), // 5% slippage + referrer: ethers.constants.AddressZero, trackingCode: ethers.constants.HashZero, }); - const order = await systems().PerpsMarket.getOrder(btcMarketId, 2); - assertBn.equal(order.accountId, 2); - assertBn.equal(order.marketId, btcMarketId); - assertBn.equal(order.sizeDelta, bn(1)); + const order = await systems().PerpsMarket.getOrder(2); + assertBn.equal(order.request.accountId, 2); + assertBn.equal(order.request.marketId, btcMarketId); + assertBn.equal(order.request.sizeDelta, bn(1)); }); }); }); diff --git a/markets/perps-market/test/integration/Orders/OffchainAsyncOrder.price.test.ts b/markets/perps-market/test/integration/Orders/OffchainAsyncOrder.price.test.ts index 4f0bae8ab2..c219a8c72c 100644 --- a/markets/perps-market/test/integration/Orders/OffchainAsyncOrder.price.test.ts +++ b/markets/perps-market/test/integration/Orders/OffchainAsyncOrder.price.test.ts @@ -46,7 +46,7 @@ describe('Offchain Async Order - Price tests', () => { }); before('setup bytes data', () => { - extraData = ethers.utils.defaultAbiCoder.encode(['uint128', 'uint128'], [ethMarketId, 2]); + extraData = ethers.utils.defaultAbiCoder.encode(['uint128'], [2]); }); const restoreToSetCollateralTime = snapshotCheckpoint(provider); @@ -84,6 +84,7 @@ describe('Offchain Async Order - Price tests', () => { sizeDelta: iter.sizeDelta, settlementStrategyId: 0, acceptablePrice: iter.acceptablePrice, + referrer: ethers.constants.AddressZero, trackingCode: ethers.constants.HashZero, }); startTime = await getTxTime(provider(), tx); @@ -214,6 +215,7 @@ describe('Offchain Async Order - Price tests', () => { sizeDelta: iter.sizeDelta, settlementStrategyId: 0, acceptablePrice: iter.tightFillPrice, + referrer: ethers.constants.AddressZero, trackingCode: ethers.constants.HashZero, }), `AcceptablePriceExceeded("${iter.limitFillPrice}", "${iter.tightFillPrice}")` @@ -232,6 +234,7 @@ describe('Offchain Async Order - Price tests', () => { sizeDelta: iter.sizeDelta, settlementStrategyId: 0, acceptablePrice: iter.limitFillPrice, + referrer: ethers.constants.AddressZero, trackingCode: ethers.constants.HashZero, }); const startTime = await getTxTime(provider(), tx); diff --git a/markets/perps-market/test/integration/Orders/OffchainAsyncOrder.referrer.test.ts b/markets/perps-market/test/integration/Orders/OffchainAsyncOrder.referrer.test.ts new file mode 100644 index 0000000000..7ea6ffb480 --- /dev/null +++ b/markets/perps-market/test/integration/Orders/OffchainAsyncOrder.referrer.test.ts @@ -0,0 +1,400 @@ +import { ethers } from 'ethers'; +import assertBn from '@synthetixio/core-utils/utils/assertions/assert-bignumber'; +import assertRevert from '@synthetixio/core-utils/utils/assertions/assert-revert'; +import { DEFAULT_SETTLEMENT_STRATEGY, bn, bootstrapMarkets } from '../bootstrap'; +import { openPosition } from '../helpers'; +import Wei, { wei } from '@synthetixio/wei'; + +describe('OffchainAsyncOrder - feeCollector - referrer', () => { + const _ETH_PRICE = bn(2000); + const { + systems, + superMarketId, + perpsMarkets, + signers, + owner, + provider, + trader1, + trader2, + keeper, + } = bootstrapMarkets({ + synthMarkets: [], + perpsMarkets: [ + { + requestedMarketId: 25, + name: 'Ether', + token: 'snxETH', + price: _ETH_PRICE, + // setting to 0 to avoid funding and p/d price change affecting pnl + fundingParams: { skewScale: bn(10_000), maxFundingVelocity: bn(0) }, + orderFees: { + makerFee: bn(0.0003), // 3bps + takerFee: bn(0.0008), // 8bps + }, + }, + ], + traderAccountIds: [2, 3], + }); + + let marketId: ethers.BigNumber, + settlementStrategyId: ethers.BigNumber, + referrer: ethers.Signer, + settlementReward: Wei; + before('identify actors', () => { + marketId = perpsMarkets()[0].marketId(); + settlementStrategyId = perpsMarkets()[0].strategyId(); + settlementReward = wei(DEFAULT_SETTLEMENT_STRATEGY.settlementReward); + referrer = signers()[8]; + }); + + before('add margin', async () => { + await systems().PerpsMarket.connect(trader1()).modifyCollateral(2, 0, bn(100_000)); + await systems().PerpsMarket.connect(trader2()).modifyCollateral(3, 0, bn(100_000)); + }); + + const feeCollectorRatio = wei(0.25), // 25% + referrerRatio = wei(0.1); // 10% + before('set fee collector and referral', async () => { + await systems().FeeCollectorMock.mockSetFeeRatio(feeCollectorRatio.toBN()); // 25% + await systems() + .PerpsMarket.connect(owner()) + .setFeeCollector(systems().FeeCollectorMock.address); + await systems() + .PerpsMarket.connect(owner()) + .updateReferrerShare(await referrer.getAddress(), referrerRatio.toBN()); // 10% + }); + + describe('with fee collector/referrer set', () => { + let expectedFees: Wei, + expectedToFeeCollector: Wei, + expectedToReferrer: Wei, + beforeWithdrawableUsd: Wei; + const sizeDelta = bn(100); + before('identify data', async () => { + beforeWithdrawableUsd = wei(await systems().Core.getWithdrawableMarketUsd(superMarketId())); + // NOTE: expected fees here does not include settlement reward + expectedFees = wei( + await systems().PerpsMarket.computeOrderFees(perpsMarkets()[0].marketId(), sizeDelta) + ); + expectedToReferrer = expectedFees.mul(referrerRatio); + expectedToFeeCollector = expectedFees.sub(expectedToReferrer).mul(feeCollectorRatio); + }); + + before('open position', async () => { + await openPosition({ + systems, + provider, + trader: trader1(), + marketId, + accountId: 2, + sizeDelta, + settlementStrategyId, + referrer: await referrer.getAddress(), + price: _ETH_PRICE, + keeper: keeper(), + }); + }); + + it('properly deducted fees from trader account', async () => { + assertBn.equal( + await systems().PerpsMarket.totalCollateralValue(2), + wei(100_000).sub(expectedFees).sub(settlementReward).toBN() + ); + }); + + it('sent referrer their configured share', async () => { + assertBn.equal( + await systems().USD.balanceOf(await referrer.getAddress()), + expectedToReferrer.toBN() + ); + }); + + it('sent fees to fee collector', async () => { + assertBn.equal( + await systems().USD.balanceOf(systems().FeeCollectorMock.address), + expectedToFeeCollector.toBN() + ); + }); + + it('fees sent from core system', async () => { + assertBn.equal( + await systems().Core.getWithdrawableMarketUsd(superMarketId()), + beforeWithdrawableUsd + .sub(expectedToReferrer) + .sub(expectedToFeeCollector) + .sub(settlementReward) + .toBN() + ); + }); + }); + + describe('with only fee collector set', () => { + let expectedToFeeCollector: Wei, previousReferrerBalance: Wei; + + const sizeDelta = bn(-50); + before('identify data', async () => { + previousReferrerBalance = wei(await systems().USD.balanceOf(await referrer.getAddress())); + // NOTE: expected fees here does not include settlement reward + const expectedFees = wei( + await systems().PerpsMarket.computeOrderFees(perpsMarkets()[0].marketId(), sizeDelta) + ); + const currentFeeCollectorBalance = wei( + await systems().USD.balanceOf(systems().FeeCollectorMock.address) + ); + expectedToFeeCollector = currentFeeCollectorBalance.add(expectedFees.mul(feeCollectorRatio)); + }); + + before('open position', async () => { + // NOTE: no referrer sent in + await openPosition({ + systems, + provider, + trader: trader2(), + marketId, + accountId: 3, + sizeDelta, + settlementStrategyId, + price: _ETH_PRICE, + keeper: keeper(), + }); + }); + + it('sent no fees to referrer', async () => { + assertBn.equal( + await systems().USD.balanceOf(await referrer.getAddress()), + previousReferrerBalance.toBN() + ); + }); + + it('sent fees to fee collector', async () => { + assertBn.equal( + await systems().USD.balanceOf(systems().FeeCollectorMock.address), + expectedToFeeCollector.toBN() + ); + }); + }); + + describe('with fee collector ratio set to 0%', () => { + before('set fee collector to 0%', async () => { + await systems().FeeCollectorMock.mockSetFeeRatio(0); + }); + + let expectedToReferrer: Wei, previousFeeCollectorBalance: Wei; + const sizeDelta = bn(20); + before('identify data', async () => { + previousFeeCollectorBalance = wei( + await systems().USD.balanceOf(systems().FeeCollectorMock.address) + ); + // NOTE: expected fees here does not include settlement reward + const expectedFees = wei( + await systems().PerpsMarket.computeOrderFees(perpsMarkets()[0].marketId(), sizeDelta) + ); + const currentReferrerBalance = wei( + await systems().USD.balanceOf(await referrer.getAddress()) + ); + expectedToReferrer = currentReferrerBalance.add(expectedFees.mul(referrerRatio)); + }); + + before('open position', async () => { + await openPosition({ + systems, + provider, + trader: trader1(), + marketId, + accountId: 2, + sizeDelta, + referrer: await referrer.getAddress(), + settlementStrategyId, + price: _ETH_PRICE, + keeper: keeper(), + }); + }); + + it('sent fees to referrer', async () => { + assertBn.equal( + await systems().USD.balanceOf(await referrer.getAddress()), + expectedToReferrer.toBN() + ); + }); + + it('sent fees to fee collector', async () => { + assertBn.equal( + await systems().USD.balanceOf(systems().FeeCollectorMock.address), + previousFeeCollectorBalance.toBN() + ); + }); + }); + + describe('fee collector set to above 100%', () => { + before(async () => { + await systems().FeeCollectorMock.mockSetFeeRatio(bn(1.25)); + }); + + let expectedToReferrer: Wei, expectedToFeeCollector: Wei; + const sizeDelta = bn(25); + before('identify data', async () => { + // NOTE: expected fees here does not include settlement reward + const expectedFees = wei( + await systems().PerpsMarket.computeOrderFees(perpsMarkets()[0].marketId(), sizeDelta) + ); + const currentFeeCollectorBalance = wei( + await systems().USD.balanceOf(systems().FeeCollectorMock.address) + ); + const currentReferrerBalance = wei( + await systems().USD.balanceOf(await referrer.getAddress()) + ); + expectedToReferrer = currentReferrerBalance.add(expectedFees.mul(referrerRatio)); + // rest of the fees go to fee collector + expectedToFeeCollector = currentFeeCollectorBalance + .add(expectedFees) + .sub(expectedFees.mul(referrerRatio)); + }); + + before('open position', async () => { + await openPosition({ + systems, + provider, + trader: trader1(), + marketId, + accountId: 2, + sizeDelta, + referrer: await referrer.getAddress(), + settlementStrategyId, + price: _ETH_PRICE, + keeper: keeper(), + }); + }); + + it('sent fees to referrer', async () => { + assertBn.equal( + await systems().USD.balanceOf(await referrer.getAddress()), + expectedToReferrer.toBN() + ); + }); + + it('sent fees to fee collector', async () => { + assertBn.equal( + await systems().USD.balanceOf(systems().FeeCollectorMock.address), + expectedToFeeCollector.toBN() + ); + }); + }); + + describe('only referrer set', () => { + before('set fee collector to zero address', async () => { + await systems().PerpsMarket.setFeeCollector(ethers.constants.AddressZero); + }); + + let expectedToReferrer: Wei, previousFeeCollectorBalance: Wei; + const sizeDelta = bn(75); + before('identify data', async () => { + previousFeeCollectorBalance = wei( + await systems().USD.balanceOf(systems().FeeCollectorMock.address) + ); + // NOTE: expected fees here does not include settlement reward + const expectedFees = wei( + await systems().PerpsMarket.computeOrderFees(perpsMarkets()[0].marketId(), sizeDelta) + ); + const currentReferrerBalance = wei( + await systems().USD.balanceOf(await referrer.getAddress()) + ); + expectedToReferrer = currentReferrerBalance.add(expectedFees.mul(referrerRatio)); + }); + + before('open position', async () => { + await openPosition({ + systems, + provider, + trader: trader2(), + marketId, + accountId: 3, + sizeDelta, + referrer: await referrer.getAddress(), + settlementStrategyId, + price: _ETH_PRICE, + keeper: keeper(), + }); + }); + + it('sent fees to referrer', async () => { + assertBn.equal( + await systems().USD.balanceOf(await referrer.getAddress()), + expectedToReferrer.toBN() + ); + }); + + it('sent fees to fee collector', async () => { + assertBn.equal( + await systems().USD.balanceOf(systems().FeeCollectorMock.address), + previousFeeCollectorBalance.toBN() + ); + }); + }); + + describe('update referrer share failures', () => { + it('reverts when set above 100%', async () => { + await assertRevert( + systems() + .PerpsMarket.connect(owner()) + .updateReferrerShare(await referrer.getAddress(), bn(1.1)), + 'InvalidReferrerShareRatio' + ); + }); + }); + + describe('referrer share set to 0', () => { + before(async () => { + await systems() + .PerpsMarket.connect(owner()) + .updateReferrerShare(await referrer.getAddress(), 0); + }); + + let previousReferrerBalance: Wei, + previousFeeCollectorBalance: Wei, + previousWithdrawableUsd: Wei; + const sizeDelta = bn(50); + before('identify data', async () => { + previousFeeCollectorBalance = wei( + await systems().USD.balanceOf(systems().FeeCollectorMock.address) + ); + previousReferrerBalance = wei(await systems().USD.balanceOf(await referrer.getAddress())); + previousWithdrawableUsd = wei(await systems().Core.getWithdrawableMarketUsd(superMarketId())); + }); + + before('open position', async () => { + await openPosition({ + systems, + provider, + trader: trader2(), + marketId, + accountId: 3, + sizeDelta, + referrer: await referrer.getAddress(), + settlementStrategyId, + price: _ETH_PRICE, + keeper: keeper(), + }); + }); + + it('sent fees to referrer', async () => { + assertBn.equal( + await systems().USD.balanceOf(await referrer.getAddress()), + previousReferrerBalance.toBN() + ); + }); + + it('sent fees to fee collector', async () => { + assertBn.equal( + await systems().USD.balanceOf(systems().FeeCollectorMock.address), + previousFeeCollectorBalance.toBN() + ); + }); + + it('kept fees in the core system', async () => { + assertBn.equal( + await systems().Core.getWithdrawableMarketUsd(superMarketId()), + previousWithdrawableUsd.sub(settlementReward).toBN() + ); + }); + }); +}); diff --git a/markets/perps-market/test/integration/Orders/OffchainAsyncOrder.settle.test.ts b/markets/perps-market/test/integration/Orders/OffchainAsyncOrder.settle.test.ts index c8ca65aad0..1f7a863317 100644 --- a/markets/perps-market/test/integration/Orders/OffchainAsyncOrder.settle.test.ts +++ b/markets/perps-market/test/integration/Orders/OffchainAsyncOrder.settle.test.ts @@ -43,25 +43,15 @@ describe('Settle Offchain Async Order test', () => { describe('failures before commiting orders', () => { describe('using settle', () => { - it('reverts if market id is incorrect', async () => { - await assertRevert( - systems().PerpsMarket.connect(trader1()).settle(1337, 2), - 'OrderNotValid()' - ); - }); - it('reverts if account id is incorrect (not valid order)', async () => { await assertRevert( - systems().PerpsMarket.connect(trader1()).settle(ethMarketId, 1337), + systems().PerpsMarket.connect(trader1()).settle(1337), 'OrderNotValid()' ); }); it('reverts if order was not settled before (not valid order)', async () => { - await assertRevert( - systems().PerpsMarket.connect(trader1()).settle(ethMarketId, 2), - 'OrderNotValid()' - ); + await assertRevert(systems().PerpsMarket.connect(trader1()).settle(2), 'OrderNotValid()'); }); }); @@ -83,21 +73,8 @@ describe('Settle Offchain Async Order test', () => { updateFee = await systems().MockPyth.getUpdateFee([pythPriceData]); }); - it('reverts if market id is incorrect', async () => { - extraData = ethers.utils.defaultAbiCoder.encode(['uint128', 'uint128'], [1337, 2]); - await assertRevert( - systems() - .PerpsMarket.connect(keeper()) - .settlePythOrder(pythPriceData, extraData, { value: updateFee }), - 'OrderNotValid()' - ); - }); - it('reverts if account id is incorrect (not valid order)', async () => { - extraData = ethers.utils.defaultAbiCoder.encode( - ['uint128', 'uint128'], - [ethMarketId, 1337] - ); + extraData = ethers.utils.defaultAbiCoder.encode(['uint128'], [1337]); await assertRevert( systems() .PerpsMarket.connect(keeper()) @@ -107,7 +84,7 @@ describe('Settle Offchain Async Order test', () => { }); it('reverts if order was not settled before (not valid order)', async () => { - extraData = ethers.utils.defaultAbiCoder.encode(['uint128', 'uint128'], [ethMarketId, 2]); + extraData = ethers.utils.defaultAbiCoder.encode(['uint128'], [2]); await assertRevert( systems() .PerpsMarket.connect(keeper()) @@ -190,13 +167,14 @@ describe('Settle Offchain Async Order test', () => { sizeDelta: bn(1), settlementStrategyId: 0, acceptablePrice: bn(1050), // 5% slippage + referrer: ethers.constants.AddressZero, trackingCode: ethers.constants.HashZero, }); startTime = await getTxTime(provider(), tx); }); before('setup bytes data', () => { - extraData = ethers.utils.defaultAbiCoder.encode(['uint128', 'uint128'], [ethMarketId, 2]); + extraData = ethers.utils.defaultAbiCoder.encode(['uint128'], [2]); pythCallData = ethers.utils.solidityPack( ['bytes32', 'uint64'], [ @@ -213,8 +191,8 @@ describe('Settle Offchain Async Order test', () => { it('with settle', async () => { await assertRevert( - systems().PerpsMarket.connect(trader1()).settle(ethMarketId, 2), - 'SettlementWindowExpired' + systems().PerpsMarket.connect(trader1()).settle(2), + 'SettlementWindowNotOpen' ); }); @@ -233,7 +211,7 @@ describe('Settle Offchain Async Order test', () => { systems() .PerpsMarket.connect(keeper()) .settlePythOrder(validPythPriceData, extraData, { value: updateFee }), - 'SettlementWindowExpired' + 'SettlementWindowNotOpen' ); }); }); @@ -254,7 +232,7 @@ describe('Settle Offchain Async Order test', () => { it('with settle', async () => { await assertRevert( - systems().PerpsMarket.connect(trader1()).settle(ethMarketId, 2), + systems().PerpsMarket.connect(trader1()).settle(2), 'SettlementWindowExpired' ); }); @@ -352,7 +330,7 @@ describe('Settle Offchain Async Order test', () => { // : pythSettlementStrategy.url; await assertRevert( - systems().PerpsMarket.connect(keeper()).settle(ethMarketId, 2), + systems().PerpsMarket.connect(keeper()).settle(2), `OffchainLookup("${systems().PerpsMarket.address}", "${ DEFAULT_SETTLEMENT_STRATEGY.url }", "${pythCallData}", "${functionSig}", "${extraData}")` @@ -400,6 +378,8 @@ describe('Settle Offchain Async Order test', () => { sizeDelta, newPositionSize, totalFees, + 0, // referral fees + 0, // collected fees settlementReward, trackingCode, msgSender, diff --git a/markets/perps-market/test/integration/bootstrap/bootstrap.ts b/markets/perps-market/test/integration/bootstrap/bootstrap.ts index a1af4ce9e1..4c3fcbcc36 100644 --- a/markets/perps-market/test/integration/bootstrap/bootstrap.ts +++ b/markets/perps-market/test/integration/bootstrap/bootstrap.ts @@ -1,7 +1,7 @@ import { coreBootstrap } from '@synthetixio/router/dist/utils/tests'; import { wei } from '@synthetixio/wei'; import { ethers } from 'ethers'; -import { PerpsMarketProxy, AccountProxy } from '../../generated/typechain'; +import { FeeCollectorMock, PerpsMarketProxy, AccountProxy } from '../../generated/typechain'; import { SpotMarketProxy, SynthRouter } from '@synthetixio/spot-market/test/generated/typechain'; import { SynthArguments, bootstrapSynthMarkets } from '@synthetixio/spot-market/test/common'; import { PerpsMarketData, bootstrapPerpsMarkets, bootstrapTraders } from '.'; @@ -20,6 +20,7 @@ type Proxies = { AccountProxy: AccountProxy; ['spotMarket.SynthRouter']: SynthRouter; ['MockPyth']: MockPyth; + ['FeeCollectorMock']: FeeCollectorMock; }; export type Systems = { @@ -31,6 +32,7 @@ export type Systems = { OracleManager: OracleManagerProxy; PerpsMarket: PerpsMarketProxy; Account: AccountProxy; + FeeCollectorMock: FeeCollectorMock; Synth: (address: string) => SynthRouter; }; @@ -54,6 +56,7 @@ export function bootstrap() { PerpsMarket: getContract('PerpsMarketProxy'), Account: getContract('AccountProxy'), MockPyth: getContract('MockPyth'), + FeeCollectorMock: getContract('FeeCollectorMock'), Synth: (address: string) => getContract('spotMarket.SynthRouter', address), }; }); diff --git a/markets/perps-market/test/integration/helpers/openPosition.ts b/markets/perps-market/test/integration/helpers/openPosition.ts index 900f879bf1..bfdd0cca90 100644 --- a/markets/perps-market/test/integration/helpers/openPosition.ts +++ b/markets/perps-market/test/integration/helpers/openPosition.ts @@ -13,6 +13,7 @@ export type OpenPositionData = { price: ethers.BigNumber; trackingCode?: string; keeper: ethers.Signer; + referrer?: string; systems: () => Systems; provider: () => ethers.providers.JsonRpcProvider; }; @@ -27,6 +28,7 @@ export const openPosition = async (data: OpenPositionData) => { sizeDelta, settlementStrategyId, price, + referrer, trackingCode, keeper, } = data; @@ -45,6 +47,7 @@ export const openPosition = async (data: OpenPositionData) => { sizeDelta, settlementStrategyId, acceptablePrice: sizeDelta.gt(0) ? price.mul(2) : price.div(2), + referrer: referrer || ethers.constants.AddressZero, trackingCode: trackingCode ?? ethers.constants.HashZero, }); @@ -55,7 +58,6 @@ export const openPosition = async (data: OpenPositionData) => { const settleTx = await settleOrder({ systems, keeper, - marketId, accountId, offChainPrice: toNum(price), settlementTime, diff --git a/markets/perps-market/test/integration/helpers/settleHelper.ts b/markets/perps-market/test/integration/helpers/settleHelper.ts index 9d1fb37172..d79954f156 100644 --- a/markets/perps-market/test/integration/helpers/settleHelper.ts +++ b/markets/perps-market/test/integration/helpers/settleHelper.ts @@ -4,7 +4,6 @@ import { Systems } from '../bootstrap'; export type SettleOrderData = { systems: () => Systems; keeper: ethers.Signer; - marketId: ethers.BigNumber; accountId: number; offChainPrice: ethers.BigNumberish; settlementTime: number; @@ -14,17 +13,13 @@ export type SettleOrderData = { export const settleOrder = async ({ systems, keeper, - marketId, accountId, offChainPrice, settlementTime, feedId, }: SettleOrderData): Promise => { // create extraData based on market/account id - const extraData = ethers.utils.defaultAbiCoder.encode( - ['uint128', 'uint128'], - [marketId, accountId] - ); + const extraData = ethers.utils.defaultAbiCoder.encode(['uint128'], [accountId]); // build pyth data const pythPriceExpotential = 6; diff --git a/markets/spot-market/contracts/interfaces/IMarketConfigurationModule.sol b/markets/spot-market/contracts/interfaces/IMarketConfigurationModule.sol index dbd5478fca..ecbe5c8c9d 100644 --- a/markets/spot-market/contracts/interfaces/IMarketConfigurationModule.sol +++ b/markets/spot-market/contracts/interfaces/IMarketConfigurationModule.sol @@ -74,7 +74,7 @@ interface IMarketConfigurationModule { event WrapperFeesSet(uint256 indexed synthMarketId, int256 wrapFee, int256 unwrapFee); /** - * @notice Emitted when the owner of the market has changed. + * @notice Emitted when the share percentage for a referrer address has been updated. * @param marketId Id of the market * @param referrer The address of the referrer * @param sharePercentage The new share percentage for the referrer diff --git a/markets/spot-market/contracts/modules/AsyncOrderSettlementModule.sol b/markets/spot-market/contracts/modules/AsyncOrderSettlementModule.sol index f8d9fcaf4f..907921105a 100644 --- a/markets/spot-market/contracts/modules/AsyncOrderSettlementModule.sol +++ b/markets/spot-market/contracts/modules/AsyncOrderSettlementModule.sol @@ -191,7 +191,7 @@ contract AsyncOrderSettlementModule is IAsyncOrderSettlementModule { collectedFees = config.collectFees( marketId, fees, - msg.sender, + trader, asyncOrderClaim.referrer, spotMarketFactory, Transaction.Type.ASYNC_BUY From f440e7fa3aa2897d12900af5b0d5559dda661e92 Mon Sep 17 00:00:00 2001 From: Leonardo Massazza Date: Mon, 31 Jul 2023 20:39:08 +0100 Subject: [PATCH 21/63] Fix minimumCredit (plus small fixes) (#1736) * fix minimumCredit (plus small fixes) * lint --- .../interfaces/IMarketConfigurationModule.sol | 4 +- .../contracts/mocks/FeeCollectorMock.sol | 2 +- .../contracts/modules/AsyncOrderModule.sol | 8 -- .../modules/MarketConfigurationModule.sol | 4 +- .../contracts/modules/PerpsAccountModule.sol | 2 +- .../modules/PerpsMarketFactoryModule.sol | 35 ++++--- .../contracts/storage/GlobalPerpsMarket.sol | 1 - .../contracts/storage/PerpsAccount.sol | 2 +- .../contracts/storage/PerpsMarketFactory.sol | 2 - .../Market/Market.minimumCredit.test.ts | 93 +++++++++++++++++++ .../Market/MarketConfiguration.test.ts | 2 +- 11 files changed, 123 insertions(+), 32 deletions(-) create mode 100644 markets/perps-market/test/integration/Market/Market.minimumCredit.test.ts diff --git a/markets/perps-market/contracts/interfaces/IMarketConfigurationModule.sol b/markets/perps-market/contracts/interfaces/IMarketConfigurationModule.sol index 6a3b8b39c9..4c51630d6b 100644 --- a/markets/perps-market/contracts/interfaces/IMarketConfigurationModule.sol +++ b/markets/perps-market/contracts/interfaces/IMarketConfigurationModule.sol @@ -80,7 +80,7 @@ interface IMarketConfigurationModule { * @param marketId udpates funding parameters to this specific market. * @param lockedOiRatioD18 the locked OI ratio skew scale (as decimal with 18 digits precision). */ - event LockedOiRatioD18Set(uint128 indexed marketId, uint256 lockedOiRatioD18); + event LockedOiRatioSet(uint128 indexed marketId, uint256 lockedOiRatioD18); /** * @notice Gets fired when a settlement strategy is enabled or disabled. @@ -240,5 +240,5 @@ interface IMarketConfigurationModule { * @param marketId id of the market. * @return lockedOiRatioD18 the locked OI ratio skew scale (as decimal with 18 digits precision). */ - function getLockedOiRatioD18(uint128 marketId) external view returns (uint256 lockedOiRatioD18); + function getLockedOiRatio(uint128 marketId) external view returns (uint256 lockedOiRatioD18); } diff --git a/markets/perps-market/contracts/mocks/FeeCollectorMock.sol b/markets/perps-market/contracts/mocks/FeeCollectorMock.sol index 1fef86641e..7418edca37 100644 --- a/markets/perps-market/contracts/mocks/FeeCollectorMock.sol +++ b/markets/perps-market/contracts/mocks/FeeCollectorMock.sol @@ -5,7 +5,7 @@ import "@synthetixio/core-modules/contracts/interfaces/ITokenModule.sol"; import "../interfaces/external/IFeeCollector.sol"; contract FeeCollectorMock is IFeeCollector { - uint feeRatioD18; + uint internal feeRatioD18; function mockSetFeeRatio(uint _feeRatio) external { feeRatioD18 = _feeRatio; diff --git a/markets/perps-market/contracts/modules/AsyncOrderModule.sol b/markets/perps-market/contracts/modules/AsyncOrderModule.sol index 0b343c53aa..430e8e8e48 100644 --- a/markets/perps-market/contracts/modules/AsyncOrderModule.sol +++ b/markets/perps-market/contracts/modules/AsyncOrderModule.sol @@ -5,18 +5,14 @@ import {SafeCastU256, SafeCastI256} from "@synthetixio/core-contracts/contracts/ import {DecimalMath} from "@synthetixio/core-contracts/contracts/utils/DecimalMath.sol"; import {Account} from "@synthetixio/main/contracts/storage/Account.sol"; import {AccountRBAC} from "@synthetixio/main/contracts/storage/AccountRBAC.sol"; -import {IPythVerifier} from "../interfaces/external/IPythVerifier.sol"; import {IAsyncOrderModule} from "../interfaces/IAsyncOrderModule.sol"; -import {PerpsAccount, SNX_USD_MARKET_ID} from "../storage/PerpsAccount.sol"; import {MathUtil} from "../utils/MathUtil.sol"; import {PerpsMarket} from "../storage/PerpsMarket.sol"; import {AsyncOrder} from "../storage/AsyncOrder.sol"; -import {Position} from "../storage/Position.sol"; import {PerpsPrice} from "../storage/PerpsPrice.sol"; import {GlobalPerpsMarket} from "../storage/GlobalPerpsMarket.sol"; import {PerpsMarketConfiguration} from "../storage/PerpsMarketConfiguration.sol"; import {SettlementStrategy} from "../storage/SettlementStrategy.sol"; -import {PerpsMarketFactory} from "../storage/PerpsMarketFactory.sol"; /** * @title Module for committing and settling async orders. @@ -27,17 +23,13 @@ contract AsyncOrderModule is IAsyncOrderModule { using DecimalMath for uint256; using DecimalMath for int64; using PerpsPrice for PerpsPrice.Data; - using PerpsAccount for PerpsAccount.Data; using PerpsMarket for PerpsMarket.Data; using AsyncOrder for AsyncOrder.Data; using SettlementStrategy for SettlementStrategy.Data; - using PerpsMarketFactory for PerpsMarketFactory.Data; using GlobalPerpsMarket for GlobalPerpsMarket.Data; using PerpsMarketConfiguration for PerpsMarketConfiguration.Data; - using Position for Position.Data; using SafeCastU256 for uint256; using SafeCastI256 for int256; - using PerpsAccount for PerpsAccount.Data; /** * @inheritdoc IAsyncOrderModule diff --git a/markets/perps-market/contracts/modules/MarketConfigurationModule.sol b/markets/perps-market/contracts/modules/MarketConfigurationModule.sol index 228c2582d6..f4f10918cd 100644 --- a/markets/perps-market/contracts/modules/MarketConfigurationModule.sol +++ b/markets/perps-market/contracts/modules/MarketConfigurationModule.sol @@ -143,7 +143,7 @@ contract MarketConfigurationModule is IMarketConfigurationModule { OwnableStorage.onlyOwner(); PerpsMarketConfiguration.Data storage config = PerpsMarketConfiguration.load(marketId); config.lockedOiRatioD18 = lockedOiRatioD18; - emit LockedOiRatioD18Set(marketId, lockedOiRatioD18); + emit LockedOiRatioSet(marketId, lockedOiRatioD18); } /** @@ -221,7 +221,7 @@ contract MarketConfigurationModule is IMarketConfigurationModule { /** * @inheritdoc IMarketConfigurationModule */ - function getLockedOiRatioD18(uint128 marketId) external view override returns (uint256) { + function getLockedOiRatio(uint128 marketId) external view override returns (uint256) { PerpsMarketConfiguration.Data storage config = PerpsMarketConfiguration.load(marketId); return config.lockedOiRatioD18; diff --git a/markets/perps-market/contracts/modules/PerpsAccountModule.sol b/markets/perps-market/contracts/modules/PerpsAccountModule.sol index 767386d231..141203a90b 100644 --- a/markets/perps-market/contracts/modules/PerpsAccountModule.sol +++ b/markets/perps-market/contracts/modules/PerpsAccountModule.sol @@ -51,7 +51,7 @@ contract PerpsAccountModule is IPerpsAccountModule { globalPerpsMarket.checkLiquidation(accountId); PerpsAccount.Data storage account = PerpsAccount.create(accountId); - uint128 perpsMarketId = PerpsMarketFactory.load().perpsMarketId; + uint128 perpsMarketId = perpsMarketFactory.perpsMarketId; AsyncOrder.checkPendingOrder(account.id); diff --git a/markets/perps-market/contracts/modules/PerpsMarketFactoryModule.sol b/markets/perps-market/contracts/modules/PerpsMarketFactoryModule.sol index 98dd4ebf72..d69d18f2ff 100644 --- a/markets/perps-market/contracts/modules/PerpsMarketFactoryModule.sol +++ b/markets/perps-market/contracts/modules/PerpsMarketFactoryModule.sol @@ -1,26 +1,19 @@ //SPDX-License-Identifier: MIT pragma solidity >=0.8.11 <0.9.0; -import {IMarketManagerModule} from "@synthetixio/main/contracts/interfaces/IMarketManagerModule.sol"; -import {AssociatedSystemsModule, AssociatedSystem} from "@synthetixio/core-modules/contracts/modules/AssociatedSystemsModule.sol"; -import {InitializableMixin} from "@synthetixio/core-contracts/contracts/initializable/InitializableMixin.sol"; import {OwnableStorage} from "@synthetixio/core-contracts/contracts/ownership/OwnableStorage.sol"; import {ITokenModule} from "@synthetixio/core-modules/contracts/interfaces/ITokenModule.sol"; -import {INodeModule} from "@synthetixio/oracle-manager/contracts/interfaces/INodeModule.sol"; import {FeatureFlag} from "@synthetixio/core-modules/contracts/storage/FeatureFlag.sol"; import {IERC165} from "@synthetixio/core-contracts/contracts/interfaces/IERC165.sol"; import {DecimalMath} from "@synthetixio/core-contracts/contracts/utils/DecimalMath.sol"; import {PerpsMarketFactory} from "../storage/PerpsMarketFactory.sol"; import {GlobalPerpsMarket} from "../storage/GlobalPerpsMarket.sol"; -import {GlobalPerpsMarketConfiguration} from "../storage/GlobalPerpsMarketConfiguration.sol"; import {PerpsMarket} from "../storage/PerpsMarket.sol"; import {PerpsPrice} from "../storage/PerpsPrice.sol"; import {IPerpsMarketFactoryModule} from "../interfaces/IPerpsMarketFactoryModule.sol"; import {ISpotMarketSystem} from "../interfaces/external/ISpotMarketSystem.sol"; import {ISynthetixSystem} from "../interfaces/external/ISynthetixSystem.sol"; -import {AddressError} from "@synthetixio/core-contracts/contracts/errors/AddressError.sol"; import {ParameterError} from "@synthetixio/core-contracts/contracts/errors/ParameterError.sol"; -import {MathUtil} from "../utils/MathUtil.sol"; import {PerpsMarketConfiguration} from "../storage/PerpsMarketConfiguration.sol"; import {IMarket} from "@synthetixio/main/contracts/interfaces/external/IMarket.sol"; import {SetUtil} from "@synthetixio/core-contracts/contracts/utils/SetUtil.sol"; @@ -31,7 +24,6 @@ import {SafeCastU256, SafeCastI256, SafeCastU128} from "@synthetixio/core-contra * @dev See IPerpsMarketFactoryModule. */ contract PerpsMarketFactoryModule is IPerpsMarketFactoryModule { - using AssociatedSystem for AssociatedSystem.Data; using PerpsMarketFactory for PerpsMarketFactory.Data; using GlobalPerpsMarket for GlobalPerpsMarket.Data; using PerpsPrice for PerpsPrice.Data; @@ -106,6 +98,7 @@ contract PerpsMarketFactoryModule is IPerpsMarketFactoryModule { return requestedMarketId; } + // solc-ignore-next-line func-mutability function name(uint128 perpsMarketId) external view override returns (string memory) { // todo: set name on initialize? perpsMarketId; // silence unused variable warning @@ -134,15 +127,31 @@ contract PerpsMarketFactoryModule is IPerpsMarketFactoryModule { return totalDebt < 0 ? 0 : totalDebt.toUint(); } - // TODO Should revert if perpsMarketId is not correct??? return 0; } function minimumCredit(uint128 perpsMarketId) external view override returns (uint256) { - return - PerpsMarket.load(perpsMarketId).size.mulDecimal( - PerpsMarketConfiguration.load(perpsMarketId).lockedOiRatioD18 - ); + PerpsMarketFactory.Data storage factory = PerpsMarketFactory.load(); + + if (factory.perpsMarketId == perpsMarketId) { + uint accumulatedMinimumCredit; + + SetUtil.UintSet storage activeMarkets = GlobalPerpsMarket.load().activeMarkets; + uint256 activeMarketsLength = activeMarkets.length(); + for (uint i = 1; i <= activeMarketsLength; i++) { + uint128 marketId = activeMarkets.valueAt(i).to128(); + + accumulatedMinimumCredit += PerpsMarket + .load(marketId) + .size + .mulDecimal(PerpsPrice.getCurrentPrice(marketId)) + .mulDecimal(PerpsMarketConfiguration.load(marketId).lockedOiRatioD18); + } + + return accumulatedMinimumCredit; + } + + return 0; } /** diff --git a/markets/perps-market/contracts/storage/GlobalPerpsMarket.sol b/markets/perps-market/contracts/storage/GlobalPerpsMarket.sol index 77ad14a244..eacfbc4328 100644 --- a/markets/perps-market/contracts/storage/GlobalPerpsMarket.sol +++ b/markets/perps-market/contracts/storage/GlobalPerpsMarket.sol @@ -7,7 +7,6 @@ import {GlobalPerpsMarketConfiguration} from "./GlobalPerpsMarketConfiguration.s import {SafeCastU256, SafeCastI256, SafeCastU128} from "@synthetixio/core-contracts/contracts/utils/SafeCast.sol"; import {PerpsAccount} from "./PerpsAccount.sol"; import {PerpsMarketFactory} from "./PerpsMarketFactory.sol"; -import {PerpsPrice} from "./PerpsPrice.sol"; import {ISpotMarketSystem} from "../interfaces/external/ISpotMarketSystem.sol"; /** diff --git a/markets/perps-market/contracts/storage/PerpsAccount.sol b/markets/perps-market/contracts/storage/PerpsAccount.sol index db73af9343..5742994259 100644 --- a/markets/perps-market/contracts/storage/PerpsAccount.sol +++ b/markets/perps-market/contracts/storage/PerpsAccount.sol @@ -278,8 +278,8 @@ library PerpsAccount { uint128[] storage synthDeductionPriority = GlobalPerpsMarketConfiguration .load() .synthDeductionPriority; - ISpotMarketSystem spotMarket = PerpsMarketFactory.load().spotMarket; PerpsMarketFactory.Data storage factory = PerpsMarketFactory.load(); + ISpotMarketSystem spotMarket = factory.spotMarket; for (uint i = 0; i < synthDeductionPriority.length; i++) { uint128 marketId = synthDeductionPriority[i]; uint availableAmount = self.collateralAmounts[marketId]; diff --git a/markets/perps-market/contracts/storage/PerpsMarketFactory.sol b/markets/perps-market/contracts/storage/PerpsMarketFactory.sol index 39be6c45f6..c8fb90bd33 100644 --- a/markets/perps-market/contracts/storage/PerpsMarketFactory.sol +++ b/markets/perps-market/contracts/storage/PerpsMarketFactory.sol @@ -3,8 +3,6 @@ pragma solidity >=0.8.11 <0.9.0; import {ITokenModule} from "@synthetixio/core-modules/contracts/interfaces/ITokenModule.sol"; import {INodeModule} from "@synthetixio/oracle-manager/contracts/interfaces/INodeModule.sol"; -import {IMarketCollateralModule} from "@synthetixio/main/contracts/interfaces/IMarketCollateralModule.sol"; -import {AccessError} from "@synthetixio/core-contracts/contracts/errors/AccessError.sol"; import {ISynthetixSystem} from "../interfaces/external/ISynthetixSystem.sol"; import {ISpotMarketSystem} from "../interfaces/external/ISpotMarketSystem.sol"; diff --git a/markets/perps-market/test/integration/Market/Market.minimumCredit.test.ts b/markets/perps-market/test/integration/Market/Market.minimumCredit.test.ts new file mode 100644 index 0000000000..859c0f9cd3 --- /dev/null +++ b/markets/perps-market/test/integration/Market/Market.minimumCredit.test.ts @@ -0,0 +1,93 @@ +import { PerpsMarket, bn, bootstrapMarkets } from '../bootstrap'; +import { openPosition } from '../helpers'; +import { wei } from '@synthetixio/wei'; + +import assertBn from '@synthetixio/core-utils/utils/assertions/assert-bignumber'; + +describe('Market Minimum Credit', () => { + const traderAccountIds = [2, 3, 4]; + const _ETH_PRICE = bn(1000); + const _BTC_PRICE = bn(30_000); + const { systems, superMarketId, perpsMarkets, provider, trader1, trader2, keeper } = + bootstrapMarkets({ + synthMarkets: [ + { + name: 'Bitcoin', + token: 'snxBTC', + buyPrice: bn(10_000), + sellPrice: bn(10_000), + }, + ], + perpsMarkets: [ + { + requestedMarketId: bn(25), + name: 'Ether', + token: 'snxETH', + price: _ETH_PRICE, + lockedOiRatioD18: bn(0.01), + }, + { + requestedMarketId: bn(26), + name: 'Bitcoin', + token: 'BTC', + price: _BTC_PRICE, + lockedOiRatioD18: bn(0.02), + }, + ], + traderAccountIds, + }); + + let ethMarket: PerpsMarket, btcMarket: PerpsMarket; + before('identify actors', () => { + ethMarket = perpsMarkets()[0]; + btcMarket = perpsMarkets()[1]; + }); + + before('add collateral to margin', async () => { + await systems().PerpsMarket.connect(trader1()).modifyCollateral(2, 0, bn(10_000)); + await systems().PerpsMarket.connect(trader2()).modifyCollateral(3, 0, bn(10_000)); + }); + + describe('with no positions', () => { + it('should report total minimumCredit as zero', async () => { + const minimumCredit = await systems().PerpsMarket.minimumCredit(superMarketId()); + assertBn.equal(minimumCredit, bn(0)); + }); + }); + + describe('open positions', () => { + before(async () => { + await openPosition({ + systems, + provider, + trader: trader1(), + accountId: 2, + keeper: keeper(), + marketId: ethMarket.marketId(), + sizeDelta: bn(150), + settlementStrategyId: ethMarket.strategyId(), + price: bn(1000), + }); + await openPosition({ + systems, + provider, + trader: trader2(), + accountId: 3, + keeper: keeper(), + marketId: btcMarket.marketId(), + sizeDelta: bn(-5), + settlementStrategyId: btcMarket.strategyId(), + price: bn(30000), + }); + }); + + it('reports correct debt', async () => { + const minimumCredit = await systems().PerpsMarket.minimumCredit(superMarketId()); + + const ethExpectedMinCredit = wei(150).mul(_ETH_PRICE).mul(wei(0.01)); // size * price * lockedOiRatio + const btcExpectedMinCredit = wei(5).mul(_BTC_PRICE).mul(wei(0.02)); + + assertBn.equal(minimumCredit, ethExpectedMinCredit.add(btcExpectedMinCredit).bn); + }); + }); +}); diff --git a/markets/perps-market/test/integration/Market/MarketConfiguration.test.ts b/markets/perps-market/test/integration/Market/MarketConfiguration.test.ts index 1e9205492f..515fc71cd3 100644 --- a/markets/perps-market/test/integration/Market/MarketConfiguration.test.ts +++ b/markets/perps-market/test/integration/Market/MarketConfiguration.test.ts @@ -165,7 +165,7 @@ describe('MarketConfiguration', async () => { await systems() .PerpsMarket.connect(owner()) .setLockedOiRatio(marketId, fixture.lockedOiPercentRatioD18), - 'LockedOiRatioD18Set(' + + 'LockedOiRatioSet(' + marketId.toString() + ', ' + fixture.lockedOiPercentRatioD18.toString() + From b257e30bc2d488bc06ed551af5e944e1dc158cff Mon Sep 17 00:00:00 2001 From: Sunny Vempati Date: Mon, 31 Jul 2023 18:03:21 -0500 Subject: [PATCH 22/63] Fix event in factory (#1737) * fix event * fix synth deduction priority setter * delete --- markets/perps-market/cannonfile.toml | 3 +++ .../contracts/modules/GlobalPerpsMarketModule.sol | 5 +++-- .../contracts/modules/PerpsMarketFactoryModule.sol | 13 +++++++------ .../storage/GlobalPerpsMarketConfiguration.sol | 11 +++++++++++ .../integration/Markets/GlobalPerpsMarket.test.ts | 2 +- 5 files changed, 25 insertions(+), 9 deletions(-) diff --git a/markets/perps-market/cannonfile.toml b/markets/perps-market/cannonfile.toml index 7ba7053e5f..8ac92e657a 100644 --- a/markets/perps-market/cannonfile.toml +++ b/markets/perps-market/cannonfile.toml @@ -162,3 +162,6 @@ target = ["PerpsMarketProxy"] func = "initializeFactory" from = "<%= settings.owner %>" depends = ['invoke.setSynthetix'] + +extra.superMarketId.event = "FactoryInitialized" +extra.superMarketId.arg = 0 diff --git a/markets/perps-market/contracts/modules/GlobalPerpsMarketModule.sol b/markets/perps-market/contracts/modules/GlobalPerpsMarketModule.sol index 58933b0740..28aca49539 100644 --- a/markets/perps-market/contracts/modules/GlobalPerpsMarketModule.sol +++ b/markets/perps-market/contracts/modules/GlobalPerpsMarketModule.sol @@ -45,8 +45,9 @@ contract GlobalPerpsMarketModule is IGlobalPerpsMarketModule { uint128[] memory newSynthDeductionPriority ) external override { OwnableStorage.onlyOwner(); - GlobalPerpsMarketConfiguration.Data storage store = GlobalPerpsMarketConfiguration.load(); - store.synthDeductionPriority = newSynthDeductionPriority; + GlobalPerpsMarketConfiguration.load().updateSynthDeductionPriority( + newSynthDeductionPriority + ); emit SynthDeductionPrioritySet(newSynthDeductionPriority); } diff --git a/markets/perps-market/contracts/modules/PerpsMarketFactoryModule.sol b/markets/perps-market/contracts/modules/PerpsMarketFactoryModule.sol index d69d18f2ff..1a7011c0b3 100644 --- a/markets/perps-market/contracts/modules/PerpsMarketFactoryModule.sol +++ b/markets/perps-market/contracts/modules/PerpsMarketFactoryModule.sol @@ -63,16 +63,17 @@ contract PerpsMarketFactoryModule is IPerpsMarketFactoryModule { PerpsMarketFactory.Data storage factory = PerpsMarketFactory.load(); + uint128 perpsMarketId; if (factory.perpsMarketId == 0) { - uint128 perpsMarketId = factory.synthetix.registerMarket(address(this)); + perpsMarketId = factory.synthetix.registerMarket(address(this)); factory.perpsMarketId = perpsMarketId; - - emit FactoryInitialized(perpsMarketId); - - return perpsMarketId; } else { - return factory.perpsMarketId; + perpsMarketId = factory.perpsMarketId; } + + emit FactoryInitialized(perpsMarketId); + + return perpsMarketId; } /** diff --git a/markets/perps-market/contracts/storage/GlobalPerpsMarketConfiguration.sol b/markets/perps-market/contracts/storage/GlobalPerpsMarketConfiguration.sol index 8e2688fa47..0f3a1d3fc2 100644 --- a/markets/perps-market/contracts/storage/GlobalPerpsMarketConfiguration.sol +++ b/markets/perps-market/contracts/storage/GlobalPerpsMarketConfiguration.sol @@ -66,6 +66,17 @@ library GlobalPerpsMarketConfiguration { ); } + function updateSynthDeductionPriority( + Data storage self, + uint128[] memory newSynthDeductionPriority + ) internal { + delete self.synthDeductionPriority; + + for (uint i = 0; i < newSynthDeductionPriority.length; i++) { + self.synthDeductionPriority.push(newSynthDeductionPriority[i]); + } + } + function collectFees( Data storage self, uint256 orderFees, diff --git a/markets/perps-market/test/integration/Markets/GlobalPerpsMarket.test.ts b/markets/perps-market/test/integration/Markets/GlobalPerpsMarket.test.ts index 90a112e7dc..bcac6e0e45 100644 --- a/markets/perps-market/test/integration/Markets/GlobalPerpsMarket.test.ts +++ b/markets/perps-market/test/integration/Markets/GlobalPerpsMarket.test.ts @@ -3,7 +3,7 @@ import { bn, bootstrapMarkets } from '../bootstrap'; import assertBn from '@synthetixio/core-utils/src/utils/assertions/assert-bignumber'; import assertRevert from '@synthetixio/core-utils/utils/assertions/assert-revert'; -describe('GlobalPerpsMarket', () => { +describe.only('GlobalPerpsMarket', () => { const { systems, perpsMarkets, trader1 } = bootstrapMarkets({ synthMarkets: [{ name: 'Ether', token: 'snxETH', buyPrice: bn(1000), sellPrice: bn(1000) }], perpsMarkets: [{ requestedMarketId: 25, name: 'Ether', token: 'snxETH', price: bn(1000) }], From f153b4fba8cd7d6f9cadd7b580132b465db80008 Mon Sep 17 00:00:00 2001 From: Sunny Vempati Date: Mon, 31 Jul 2023 18:39:59 -0500 Subject: [PATCH 23/63] remove only (#1738) --- .../test/integration/Markets/GlobalPerpsMarket.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/markets/perps-market/test/integration/Markets/GlobalPerpsMarket.test.ts b/markets/perps-market/test/integration/Markets/GlobalPerpsMarket.test.ts index bcac6e0e45..90a112e7dc 100644 --- a/markets/perps-market/test/integration/Markets/GlobalPerpsMarket.test.ts +++ b/markets/perps-market/test/integration/Markets/GlobalPerpsMarket.test.ts @@ -3,7 +3,7 @@ import { bn, bootstrapMarkets } from '../bootstrap'; import assertBn from '@synthetixio/core-utils/src/utils/assertions/assert-bignumber'; import assertRevert from '@synthetixio/core-utils/utils/assertions/assert-revert'; -describe.only('GlobalPerpsMarket', () => { +describe('GlobalPerpsMarket', () => { const { systems, perpsMarkets, trader1 } = bootstrapMarkets({ synthMarkets: [{ name: 'Ether', token: 'snxETH', buyPrice: bn(1000), sellPrice: bn(1000) }], perpsMarkets: [{ requestedMarketId: 25, name: 'Ether', token: 'snxETH', price: bn(1000) }], From cd5a637ecef829eac420aec52a71f7e3a4559582 Mon Sep 17 00:00:00 2001 From: Sunny Vempati Date: Wed, 2 Aug 2023 15:16:30 -0500 Subject: [PATCH 24/63] add new liq params (#1740) --- .../interfaces/IMarketConfigurationModule.sol | 17 ++++++++---- .../modules/MarketConfigurationModule.sol | 19 ++++++++----- .../contracts/modules/PerpsAccountModule.sol | 4 +-- .../contracts/storage/PerpsAccount.sol | 4 +-- .../storage/PerpsMarketConfiguration.sol | 17 +++++++++--- .../test/integration/Account/Margins.test.ts | 17 +++++++----- .../Account/ModifyCollateral.withdraw.test.ts | 8 +++--- .../Liquidation/Liquidation.margin.test.ts | 27 ++++++++++++------- .../Liquidation.maxLiquidationAmount.test.ts | 3 ++- .../Liquidation.multi-collateral.test.ts | 9 ++++--- .../Market/MarketConfiguration.test.ts | 17 +++++++----- .../Market/MarketDebt.withFunding.test.ts | 3 ++- .../bootstrap/bootstrapPerpsMarkets.ts | 6 +++-- 13 files changed, 100 insertions(+), 51 deletions(-) diff --git a/markets/perps-market/contracts/interfaces/IMarketConfigurationModule.sol b/markets/perps-market/contracts/interfaces/IMarketConfigurationModule.sol index 4c51630d6b..b86e6ea2af 100644 --- a/markets/perps-market/contracts/interfaces/IMarketConfigurationModule.sol +++ b/markets/perps-market/contracts/interfaces/IMarketConfigurationModule.sol @@ -62,6 +62,7 @@ interface IMarketConfigurationModule { uint128 indexed marketId, uint256 initialMarginRatioD18, uint256 maintenanceMarginRatioD18, + uint256 minimumInitialMarginRatioD18, uint256 liquidationRewardRatioD18, uint256 maxLiquidationLimitAccumulationMultiplier, uint256 maxSecondsInLiquidationWindow, @@ -132,7 +133,8 @@ interface IMarketConfigurationModule { * @notice Set liquidation parameters for a market with this function. * @param marketId id of the market to set liquidation parameters. * @param initialMarginRatioD18 the initial margin ratio (as decimal with 18 digits precision). - * @param maintenanceMarginRatioD18 the maintenance margin ratio (as decimal with 18 digits precision). + * @param minimumInitialMarginRatioD18 the minimum initial margin ratio (as decimal with 18 digits precision). + * @param maintenanceMarginScalarD18 the maintenance margin scalar relative to the initial margin ratio (as decimal with 18 digits precision). * @param liquidationRewardRatioD18 the liquidation reward ratio (as decimal with 18 digits precision). * @param maxLiquidationLimitAccumulationMultiplier the max liquidation limit accumulation multiplier. * @param maxSecondsInLiquidationWindow the max seconds in liquidation window (used together with the acc multiplier to get max liquidation per window). @@ -141,7 +143,8 @@ interface IMarketConfigurationModule { function setLiquidationParameters( uint128 marketId, uint256 initialMarginRatioD18, - uint256 maintenanceMarginRatioD18, + uint256 minimumInitialMarginRatioD18, + uint256 maintenanceMarginScalarD18, uint256 liquidationRewardRatioD18, uint256 maxLiquidationLimitAccumulationMultiplier, uint256 maxSecondsInLiquidationWindow, @@ -190,10 +193,12 @@ interface IMarketConfigurationModule { * @notice Gets liquidation parameters details of a market. * @param marketId id of the market. * @return initialMarginRatioD18 the initial margin ratio (as decimal with 18 digits precision). - * @return maintenanceMarginRatioD18 the maintenance margin ratio (as decimal with 18 digits precision). + * @return minimumInitialMarginRatioD18 the minimum initial margin ratio (as decimal with 18 digits precision). + * @return maintenanceMarginScalarD18 the maintenance margin scalar relative to the initial margin ratio (as decimal with 18 digits precision). * @return liquidationRewardRatioD18 the liquidation reward ratio (as decimal with 18 digits precision). * @return maxLiquidationLimitAccumulationMultiplier the max liquidation limit accumulation multiplier. * @return maxSecondsInLiquidationWindow the max seconds in liquidation window (used together with the acc multiplier to get max liquidation per window). + * @return minimumPositionMargin the minimum position margin. */ function getLiquidationParameters( uint128 marketId @@ -202,10 +207,12 @@ interface IMarketConfigurationModule { view returns ( uint256 initialMarginRatioD18, - uint256 maintenanceMarginRatioD18, + uint256 minimumInitialMarginRatioD18, + uint256 maintenanceMarginScalarD18, uint256 liquidationRewardRatioD18, uint256 maxLiquidationLimitAccumulationMultiplier, - uint256 maxSecondsInLiquidationWindow + uint256 maxSecondsInLiquidationWindow, + uint256 minimumPositionMargin ); /** diff --git a/markets/perps-market/contracts/modules/MarketConfigurationModule.sol b/markets/perps-market/contracts/modules/MarketConfigurationModule.sol index f4f10918cd..320e348429 100644 --- a/markets/perps-market/contracts/modules/MarketConfigurationModule.sol +++ b/markets/perps-market/contracts/modules/MarketConfigurationModule.sol @@ -108,7 +108,8 @@ contract MarketConfigurationModule is IMarketConfigurationModule { function setLiquidationParameters( uint128 marketId, uint256 initialMarginRatioD18, - uint256 maintenanceMarginRatioD18, + uint256 minimumInitialMarginRatioD18, + uint256 maintenanceMarginScalarD18, uint256 liquidationRewardRatioD18, uint256 maxLiquidationLimitAccumulationMultiplier, uint256 maxSecondsInLiquidationWindow, @@ -118,7 +119,8 @@ contract MarketConfigurationModule is IMarketConfigurationModule { PerpsMarketConfiguration.Data storage config = PerpsMarketConfiguration.load(marketId); config.initialMarginRatioD18 = initialMarginRatioD18; - config.maintenanceMarginRatioD18 = maintenanceMarginRatioD18; + config.maintenanceMarginScalarD18 = maintenanceMarginScalarD18; + config.minimumInitialMarginRatioD18 = minimumInitialMarginRatioD18; config.liquidationRewardRatioD18 = liquidationRewardRatioD18; config .maxLiquidationLimitAccumulationMultiplier = maxLiquidationLimitAccumulationMultiplier; @@ -128,7 +130,8 @@ contract MarketConfigurationModule is IMarketConfigurationModule { emit LiquidationParametersSet( marketId, initialMarginRatioD18, - maintenanceMarginRatioD18, + maintenanceMarginScalarD18, + minimumInitialMarginRatioD18, liquidationRewardRatioD18, maxLiquidationLimitAccumulationMultiplier, maxSecondsInLiquidationWindow, @@ -167,20 +170,24 @@ contract MarketConfigurationModule is IMarketConfigurationModule { override returns ( uint256 initialMarginRatioD18, - uint256 maintenanceMarginRatioD18, + uint256 minimumInitialMarginRatioD18, + uint256 maintenanceMarginScalarD18, uint256 liquidationRewardRatioD18, uint256 maxLiquidationLimitAccumulationMultiplier, - uint256 maxSecondsInLiquidationWindow + uint256 maxSecondsInLiquidationWindow, + uint256 minimumPositionMargin ) { PerpsMarketConfiguration.Data storage config = PerpsMarketConfiguration.load(marketId); initialMarginRatioD18 = config.initialMarginRatioD18; - maintenanceMarginRatioD18 = config.maintenanceMarginRatioD18; + minimumInitialMarginRatioD18 = config.minimumInitialMarginRatioD18; + maintenanceMarginScalarD18 = config.maintenanceMarginScalarD18; liquidationRewardRatioD18 = config.liquidationRewardRatioD18; maxLiquidationLimitAccumulationMultiplier = config .maxLiquidationLimitAccumulationMultiplier; maxSecondsInLiquidationWindow = config.maxSecondsInLiquidationWindow; + minimumPositionMargin = config.minimumPositionMargin; } /** diff --git a/markets/perps-market/contracts/modules/PerpsAccountModule.sol b/markets/perps-market/contracts/modules/PerpsAccountModule.sol index 141203a90b..3ea1eeadee 100644 --- a/markets/perps-market/contracts/modules/PerpsAccountModule.sol +++ b/markets/perps-market/contracts/modules/PerpsAccountModule.sol @@ -118,9 +118,9 @@ contract PerpsAccountModule is IPerpsAccountModule { ) external view override returns (int256 withdrawableMargin) { PerpsAccount.Data storage account = PerpsAccount.load(accountId); int256 availableMargin = account.getAvailableMargin(); - (uint256 initialMaintenanceMargin, ) = account.getAccountRequiredMargins(); + (uint256 initialRequiredMargin, ) = account.getAccountRequiredMargins(); - withdrawableMargin = availableMargin - initialMaintenanceMargin.toInt(); + withdrawableMargin = availableMargin - initialRequiredMargin.toInt(); } /** diff --git a/markets/perps-market/contracts/storage/PerpsAccount.sol b/markets/perps-market/contracts/storage/PerpsAccount.sol index 5742994259..0e06e0a078 100644 --- a/markets/perps-market/contracts/storage/PerpsAccount.sol +++ b/markets/perps-market/contracts/storage/PerpsAccount.sol @@ -139,7 +139,7 @@ library PerpsAccount { ( bool isEligible, int256 availableMargin, - uint256 initialMaintenanceMargin, + uint256 initialRequiredMargin, ) = isEligibleForLiquidation(self); @@ -148,7 +148,7 @@ library PerpsAccount { } // availableMargin can be assumed to be positive since we check for isEligible for liquidation prior - availableWithdrawableCollateralUsd = availableMargin.toUint() - initialMaintenanceMargin; + availableWithdrawableCollateralUsd = availableMargin.toUint() - initialRequiredMargin; if (amountToWithdraw > availableWithdrawableCollateralUsd) { revert InsufficientCollateralAvailableForWithdraw( diff --git a/markets/perps-market/contracts/storage/PerpsMarketConfiguration.sol b/markets/perps-market/contracts/storage/PerpsMarketConfiguration.sol index 410dfbf723..1a164c325d 100644 --- a/markets/perps-market/contracts/storage/PerpsMarketConfiguration.sol +++ b/markets/perps-market/contracts/storage/PerpsMarketConfiguration.sol @@ -28,11 +28,14 @@ library PerpsMarketConfiguration { */ uint256 initialMarginRatioD18; /** - * @dev the maintenance margin requirements for this market when opening a position + * @dev This scalar is applied to the calculated initial margin ratio * @dev this generally will be lower than initial margin but is used to determine when to liquidate a position * @dev this fraction is multiplied by the impact of the position on the skew (position size / skewScale) */ - uint256 maintenanceMarginRatioD18; + uint256 maintenanceMarginScalarD18; + /** + * @dev This ratio is multiplied by the market's notional size (size * currentPrice) to determine how much credit is required for the market to be sufficiently backed by the LPs + */ uint256 lockedOiRatioD18; /** * @dev This multiplier is applied to the max liquidation value when calculating max liquidation for a given market @@ -51,6 +54,10 @@ library PerpsMarketConfiguration { * @dev minimum position value in USD, this is a constant value added to position margin requirements (initial/maintenance) */ uint256 minimumPositionMargin; + /** + * @dev This value gets applied to the initial margin ratio to ensure there's a cap on the max leverage regardless of position size + */ + uint256 minimumInitialMarginRatioD18; } function load(uint128 marketId) internal pure returns (Data storage store) { @@ -95,8 +102,10 @@ library PerpsMarketConfiguration { uint256 sizeAbs = MathUtil.abs(size.to256()); uint256 impactOnSkew = self.skewScale == 0 ? 0 : sizeAbs.divDecimal(self.skewScale); - initialMarginRatio = impactOnSkew.mulDecimal(self.initialMarginRatioD18); - maintenanceMarginRatio = impactOnSkew.mulDecimal(self.maintenanceMarginRatioD18); + initialMarginRatio = + impactOnSkew.mulDecimal(self.initialMarginRatioD18) + + self.minimumInitialMarginRatioD18; + maintenanceMarginRatio = initialMarginRatio.mulDecimal(self.maintenanceMarginScalarD18); uint256 notional = sizeAbs.mulDecimal(price); initialMargin = notional.mulDecimal(initialMarginRatio) + self.minimumPositionMargin; diff --git a/markets/perps-market/test/integration/Account/Margins.test.ts b/markets/perps-market/test/integration/Account/Margins.test.ts index 9a1f1ef6fb..bf845ff16b 100644 --- a/markets/perps-market/test/integration/Account/Margins.test.ts +++ b/markets/perps-market/test/integration/Account/Margins.test.ts @@ -15,7 +15,8 @@ describe('Account margins test', () => { fundingParams: { skewScale: bn(100), maxFundingVelocity: bn(0) }, liquidationParams: { initialMarginFraction: bn(2), - maintenanceMarginFraction: bn(1), + minimumInitialMarginRatio: bn(0.01), + maintenanceMarginScalar: bn(0.5), maxLiquidationLimitAccumulationMultiplier: bn(1), liquidationRewardRatio: bn(0.05), maxSecondsInLiquidationWindow: bn(10), @@ -33,7 +34,8 @@ describe('Account margins test', () => { fundingParams: { skewScale: bn(1000), maxFundingVelocity: bn(0) }, liquidationParams: { initialMarginFraction: bn(2), - maintenanceMarginFraction: bn(1), + minimumInitialMarginRatio: bn(0.01), + maintenanceMarginScalar: bn(0.5), maxLiquidationLimitAccumulationMultiplier: bn(1), liquidationRewardRatio: bn(0.05), maxSecondsInLiquidationWindow: bn(10), @@ -117,12 +119,15 @@ describe('Account margins test', () => { const notionalBtcValue = wei(2).mul(wei(30_000)); const notionalEthValue = wei(20).mul(wei(2000)); - btcInitialMargin = notionalBtcValue.mul(wei(2).div(wei(btcSkewScale)).mul(wei(2))); - ethInitialMargin = notionalEthValue.mul(wei(20).div(wei(ethSkewScale)).mul(wei(2))); + const btcInitialMarginRatio = wei(2).div(wei(btcSkewScale)).mul(wei(2)).add(wei(0.01)); + const ethInitialMarginRatio = wei(20).div(wei(ethSkewScale)).mul(wei(2)).add(wei(0.01)); + + btcInitialMargin = notionalBtcValue.mul(btcInitialMarginRatio); + ethInitialMargin = notionalEthValue.mul(ethInitialMarginRatio); // maintenance margin ratio == 1 - btcMaintenanceMargin = notionalBtcValue.mul(wei(2).div(wei(btcSkewScale))); - ethMaintenanceMargin = notionalEthValue.mul(wei(20).div(wei(ethSkewScale))); + btcMaintenanceMargin = btcInitialMargin.mul(wei(0.5)); + ethMaintenanceMargin = ethInitialMargin.mul(wei(0.5)); // in above config: 1000 + 500 minimumPositionMargin = wei(1500); diff --git a/markets/perps-market/test/integration/Account/ModifyCollateral.withdraw.test.ts b/markets/perps-market/test/integration/Account/ModifyCollateral.withdraw.test.ts index 673edd7333..cf06a0f860 100644 --- a/markets/perps-market/test/integration/Account/ModifyCollateral.withdraw.test.ts +++ b/markets/perps-market/test/integration/Account/ModifyCollateral.withdraw.test.ts @@ -121,7 +121,8 @@ describe('ModifyCollateral Withdraw', () => { fundingParams: { skewScale: bn(100), maxFundingVelocity: bn(0) }, liquidationParams: { initialMarginFraction: bn(2), - maintenanceMarginFraction: bn(1), + minimumInitialMarginRatio: bn(0.01), + maintenanceMarginScalar: bn(0.5), maxLiquidationLimitAccumulationMultiplier: bn(1), liquidationRewardRatio: bn(0.05), maxSecondsInLiquidationWindow: bn(10), @@ -139,7 +140,8 @@ describe('ModifyCollateral Withdraw', () => { fundingParams: { skewScale: bn(1000), maxFundingVelocity: bn(0) }, liquidationParams: { initialMarginFraction: bn(2), - maintenanceMarginFraction: bn(1), + minimumInitialMarginRatio: bn(0.01), + maintenanceMarginScalar: bn(0.5), maxLiquidationLimitAccumulationMultiplier: bn(1), liquidationRewardRatio: bn(0.05), maxSecondsInLiquidationWindow: bn(10), @@ -290,7 +292,7 @@ describe('ModifyCollateral Withdraw', () => { systems() .PerpsMarket.connect(trader1()) .modifyCollateral(trader1AccountId, sUSDSynthId, bn(-18000)), - `InsufficientCollateralAvailableForWithdraw("${bn(15000)}", "${bn(18000)}")` + `InsufficientCollateralAvailableForWithdraw("${bn(14000)}", "${bn(18000)}")` ); }); diff --git a/markets/perps-market/test/integration/Liquidation/Liquidation.margin.test.ts b/markets/perps-market/test/integration/Liquidation/Liquidation.margin.test.ts index 0986878bdc..f73328d0db 100644 --- a/markets/perps-market/test/integration/Liquidation/Liquidation.margin.test.ts +++ b/markets/perps-market/test/integration/Liquidation/Liquidation.margin.test.ts @@ -14,7 +14,8 @@ describe('Liquidation - margin', async () => { fundingParams: { skewScale: bn(100), maxFundingVelocity: bn(0) }, liquidationParams: { initialMarginFraction: bn(2), - maintenanceMarginFraction: bn(1), + minimumInitialMarginRatio: bn(0.01), + maintenanceMarginScalar: bn(0.5), maxLiquidationLimitAccumulationMultiplier: bn(1), liquidationRewardRatio: bn(0.05), maxSecondsInLiquidationWindow: bn(10), @@ -32,7 +33,8 @@ describe('Liquidation - margin', async () => { fundingParams: { skewScale: bn(1000), maxFundingVelocity: bn(0) }, liquidationParams: { initialMarginFraction: bn(2), - maintenanceMarginFraction: bn(1), + minimumInitialMarginRatio: bn(0.01), + maintenanceMarginScalar: bn(0.5), maxLiquidationLimitAccumulationMultiplier: bn(1), liquidationRewardRatio: bn(0.05), maxSecondsInLiquidationWindow: bn(10), @@ -50,7 +52,8 @@ describe('Liquidation - margin', async () => { fundingParams: { skewScale: bn(100_000), maxFundingVelocity: bn(0) }, liquidationParams: { initialMarginFraction: bn(2), - maintenanceMarginFraction: bn(1), + minimumInitialMarginRatio: bn(0.01), + maintenanceMarginScalar: bn(0.5), maxLiquidationLimitAccumulationMultiplier: bn(1), liquidationRewardRatio: bn(0.05), maxSecondsInLiquidationWindow: bn(10), @@ -68,7 +71,8 @@ describe('Liquidation - margin', async () => { fundingParams: { skewScale: bn(100_000), maxFundingVelocity: bn(0) }, liquidationParams: { initialMarginFraction: bn(1.5), - maintenanceMarginFraction: bn(0.75), + minimumInitialMarginRatio: bn(0.035), + maintenanceMarginScalar: bn(0.5), maxLiquidationLimitAccumulationMultiplier: bn(1), liquidationRewardRatio: bn(0.05), maxSecondsInLiquidationWindow: bn(10), @@ -86,7 +90,8 @@ describe('Liquidation - margin', async () => { fundingParams: { skewScale: bn(100_000), maxFundingVelocity: bn(0) }, liquidationParams: { initialMarginFraction: bn(1.5), - maintenanceMarginFraction: bn(0.75), + minimumInitialMarginRatio: bn(0.035), + maintenanceMarginScalar: bn(0.5), maxLiquidationLimitAccumulationMultiplier: bn(1), liquidationRewardRatio: bn(0.05), maxSecondsInLiquidationWindow: bn(10), @@ -271,7 +276,8 @@ describe('Liquidation - margin', async () => { before('set minimumPositionMargin for OP to 50', async () => { const opMarketId = perpsMarkets()[4].marketId(); const initialMarginFraction = bn(1.5); - const maintenanceMarginFraction = bn(0.75); + const maintenanceMarginScalar = bn(0.035); + const minimumInitialMarginRatio = bn(0.5); const maxLiquidationLimitAccumulationMultiplier = bn(1); const liquidationRewardRatio = bn(0.05); const maxSecondsInLiquidationWindow = bn(10); @@ -281,7 +287,8 @@ describe('Liquidation - margin', async () => { .setLiquidationParameters( opMarketId, initialMarginFraction, - maintenanceMarginFraction, + maintenanceMarginScalar, + minimumInitialMarginRatio, maxLiquidationLimitAccumulationMultiplier, liquidationRewardRatio, maxSecondsInLiquidationWindow, @@ -307,7 +314,7 @@ describe('Liquidation - margin', async () => { describe('price change - eligible for liquidation', () => { [ bn(31000), // btc - bn(1775), // eth + bn(1820), // eth bn(3), // link bn(1), // arb bn(1), // op, the only one that has a price change @@ -319,7 +326,7 @@ describe('Liquidation - margin', async () => { [ bn(-1150), // btc - bn(-4900), // eth + bn(-4000), // eth bn(-4100), // link bn(-5250), // arb bn(-5250), // op @@ -334,7 +341,7 @@ describe('Liquidation - margin', async () => { }); it('has correct available margin', async () => { - assertBn.equal(await systems().PerpsMarket.getAvailableMargin(2), bn(-650)); + assertBn.equal(await systems().PerpsMarket.getAvailableMargin(2), bn(250)); }); it('reverts when trying to withdraw', async () => { diff --git a/markets/perps-market/test/integration/Liquidation/Liquidation.maxLiquidationAmount.test.ts b/markets/perps-market/test/integration/Liquidation/Liquidation.maxLiquidationAmount.test.ts index 89a4f21a01..d9a5d31460 100644 --- a/markets/perps-market/test/integration/Liquidation/Liquidation.maxLiquidationAmount.test.ts +++ b/markets/perps-market/test/integration/Liquidation/Liquidation.maxLiquidationAmount.test.ts @@ -20,7 +20,8 @@ describe('Liquidation - max liquidatable amount', async () => { fundingParams: { skewScale: bn(1000), maxFundingVelocity: bn(0) }, liquidationParams: { initialMarginFraction: bn(3), - maintenanceMarginFraction: bn(2), + minimumInitialMarginRatio: bn(0), + maintenanceMarginScalar: bn(0.5), maxLiquidationLimitAccumulationMultiplier: bn(1), liquidationRewardRatio: bn(0.05), maxSecondsInLiquidationWindow: ethers.BigNumber.from(10), diff --git a/markets/perps-market/test/integration/Liquidation/Liquidation.multi-collateral.test.ts b/markets/perps-market/test/integration/Liquidation/Liquidation.multi-collateral.test.ts index 9dd507b032..abb9038b7e 100644 --- a/markets/perps-market/test/integration/Liquidation/Liquidation.multi-collateral.test.ts +++ b/markets/perps-market/test/integration/Liquidation/Liquidation.multi-collateral.test.ts @@ -17,7 +17,8 @@ describe('Liquidation - multi collateral', async () => { fundingParams: { skewScale: bn(100), maxFundingVelocity: bn(0) }, liquidationParams: { initialMarginFraction: bn(2), - maintenanceMarginFraction: bn(1), + minimumInitialMarginRatio: bn(0.01), + maintenanceMarginScalar: bn(0.5), maxLiquidationLimitAccumulationMultiplier: bn(1), liquidationRewardRatio: bn(0.01), maxSecondsInLiquidationWindow: bn(10), @@ -35,7 +36,8 @@ describe('Liquidation - multi collateral', async () => { fundingParams: { skewScale: bn(1000), maxFundingVelocity: bn(0) }, liquidationParams: { initialMarginFraction: bn(2), - maintenanceMarginFraction: bn(1), + minimumInitialMarginRatio: bn(0.01), + maintenanceMarginScalar: bn(0.5), maxLiquidationLimitAccumulationMultiplier: bn(1), liquidationRewardRatio: bn(0.02), maxSecondsInLiquidationWindow: bn(10), @@ -53,7 +55,8 @@ describe('Liquidation - multi collateral', async () => { fundingParams: { skewScale: bn(100_000), maxFundingVelocity: bn(0) }, liquidationParams: { initialMarginFraction: bn(2), - maintenanceMarginFraction: bn(1), + minimumInitialMarginRatio: bn(0.01), + maintenanceMarginScalar: bn(0.5), maxLiquidationLimitAccumulationMultiplier: bn(1), liquidationRewardRatio: bn(0.05), maxSecondsInLiquidationWindow: bn(10), diff --git a/markets/perps-market/test/integration/Market/MarketConfiguration.test.ts b/markets/perps-market/test/integration/Market/MarketConfiguration.test.ts index 515fc71cd3..3499bfbc33 100644 --- a/markets/perps-market/test/integration/Market/MarketConfiguration.test.ts +++ b/markets/perps-market/test/integration/Market/MarketConfiguration.test.ts @@ -29,7 +29,8 @@ describe('MarketConfiguration', async () => { maxFundingVelocity: bn(0.3), skewScale: bn(1), initialMarginFraction: bn(2), - maintenanceMarginFraction: bn(10), + minimumInitialMarginRatio: bn(0.01), + maintenanceMarginScalar: bn(0.5), lockedOiPercentRatioD18: bn(15), maxLiquidationLimitAccumulationMultiplier: bn(5), minimumPositionMargin: bn(50), @@ -148,13 +149,14 @@ describe('MarketConfiguration', async () => { .setLiquidationParameters( marketId, fixture.initialMarginFraction, - fixture.maintenanceMarginFraction, + fixture.minimumInitialMarginRatio, + fixture.maintenanceMarginScalar, fixture.liquidationRewardRatioD18, fixture.maxLiquidationLimitAccumulationMultiplier, fixture.maxSecondsInLiquidationWindow, fixture.minimumPositionMargin ), - `LiquidationParametersSet(${marketId.toString()}, ${fixture.initialMarginFraction.toString()}, ${fixture.maintenanceMarginFraction.toString()}, ${fixture.liquidationRewardRatioD18.toString()}, ${fixture.maxLiquidationLimitAccumulationMultiplier.toString()}, ${fixture.maxSecondsInLiquidationWindow.toString()}, ${fixture.minimumPositionMargin.toString()})`, + `LiquidationParametersSet(${marketId.toString()}, ${fixture.initialMarginFraction.toString()}, ${fixture.maintenanceMarginScalar.toString()}, ${fixture.minimumInitialMarginRatio.toString()}, ${fixture.liquidationRewardRatioD18.toString()}, ${fixture.maxLiquidationLimitAccumulationMultiplier.toString()}, ${fixture.maxSecondsInLiquidationWindow.toString()}, ${fixture.minimumPositionMargin.toString()})`, systems().PerpsMarket ); @@ -207,7 +209,8 @@ describe('MarketConfiguration', async () => { .setLiquidationParameters( marketId, fixture.initialMarginFraction, - fixture.maintenanceMarginFraction, + fixture.minimumInitialMarginRatio, + fixture.maintenanceMarginScalar, fixture.liquidationRewardRatioD18, fixture.maxLiquidationLimitAccumulationMultiplier, fixture.maxSecondsInLiquidationWindow, @@ -269,13 +272,15 @@ describe('MarketConfiguration', async () => { it('get liquidationParameters', async () => { const [ initialMarginFraction, - maintenanceMarginFraction, + minimumInitialMarginRatio, + maintenanceMarginScalar, liquidationRewardRatioD18, maxLiquidationLimitAccumulationMultiplier, maxSecondsInLiquidationWindow, ] = await systems().PerpsMarket.getLiquidationParameters(marketId); assertBn.equal(initialMarginFraction, fixture.initialMarginFraction); - assertBn.equal(maintenanceMarginFraction, fixture.maintenanceMarginFraction); + assertBn.equal(minimumInitialMarginRatio, fixture.minimumInitialMarginRatio); + assertBn.equal(maintenanceMarginScalar, fixture.maintenanceMarginScalar); assertBn.equal(liquidationRewardRatioD18, fixture.liquidationRewardRatioD18); assertBn.equal( maxLiquidationLimitAccumulationMultiplier, diff --git a/markets/perps-market/test/integration/Market/MarketDebt.withFunding.test.ts b/markets/perps-market/test/integration/Market/MarketDebt.withFunding.test.ts index 7b231ac665..c5b35ff62b 100644 --- a/markets/perps-market/test/integration/Market/MarketDebt.withFunding.test.ts +++ b/markets/perps-market/test/integration/Market/MarketDebt.withFunding.test.ts @@ -34,7 +34,8 @@ describe('Market Debt - with funding', () => { fundingParams: { skewScale: _SKEW_SCALE, maxFundingVelocity: _MAX_FUNDING_VELOCITY }, liquidationParams: { initialMarginFraction: bn(3), - maintenanceMarginFraction: bn(2), + minimumInitialMarginRatio: bn(0.01), + maintenanceMarginScalar: bn(0.5), maxLiquidationLimitAccumulationMultiplier: bn(1), liquidationRewardRatio: bn(0.05), maxSecondsInLiquidationWindow: ethers.BigNumber.from(10), diff --git a/markets/perps-market/test/integration/bootstrap/bootstrapPerpsMarkets.ts b/markets/perps-market/test/integration/bootstrap/bootstrapPerpsMarkets.ts index 9f62ec96ee..16d95fda71 100644 --- a/markets/perps-market/test/integration/bootstrap/bootstrapPerpsMarkets.ts +++ b/markets/perps-market/test/integration/bootstrap/bootstrapPerpsMarkets.ts @@ -29,7 +29,8 @@ export type PerpsMarketData = Array<{ }; liquidationParams?: { initialMarginFraction: ethers.BigNumber; - maintenanceMarginFraction: ethers.BigNumber; + minimumInitialMarginRatio: ethers.BigNumber; + maintenanceMarginScalar: ethers.BigNumber; maxLiquidationLimitAccumulationMultiplier: ethers.BigNumber; liquidationRewardRatio: ethers.BigNumber; maxSecondsInLiquidationWindow: ethers.BigNumber; @@ -145,7 +146,8 @@ export const bootstrapPerpsMarkets = ( await contracts.PerpsMarket.connect(r.owner()).setLiquidationParameters( marketId, liquidationParams.initialMarginFraction, - liquidationParams.maintenanceMarginFraction, + liquidationParams.minimumInitialMarginRatio, + liquidationParams.maintenanceMarginScalar, liquidationParams.liquidationRewardRatio, liquidationParams.maxLiquidationLimitAccumulationMultiplier, liquidationParams.maxSecondsInLiquidationWindow, From 04881068e638680dd160b77533fb2b13fa55d425 Mon Sep 17 00:00:00 2001 From: Leonardo Massazza Date: Wed, 2 Aug 2023 21:28:02 +0100 Subject: [PATCH 25/63] add revert tests (#1739) Co-authored-by: Sunny Vempati --- .../Orders/OffchainAsyncOrder.commit.test.ts | 84 ++++++++++++++----- 1 file changed, 62 insertions(+), 22 deletions(-) diff --git a/markets/perps-market/test/integration/Orders/OffchainAsyncOrder.commit.test.ts b/markets/perps-market/test/integration/Orders/OffchainAsyncOrder.commit.test.ts index 79c97fda70..2ac5307c6d 100644 --- a/markets/perps-market/test/integration/Orders/OffchainAsyncOrder.commit.test.ts +++ b/markets/perps-market/test/integration/Orders/OffchainAsyncOrder.commit.test.ts @@ -11,26 +11,27 @@ import assert from 'assert'; import { getTxTime } from '@synthetixio/core-utils/src/utils/hardhat/rpc'; describe('Commit Offchain Async Order test', () => { - const { systems, perpsMarkets, synthMarkets, provider, trader1, keeper } = bootstrapMarkets({ - synthMarkets: [ - { - name: 'Bitcoin', - token: 'snxBTC', - buyPrice: bn(10_000), - sellPrice: bn(10_000), - }, - ], - perpsMarkets: [ - { - requestedMarketId: 25, - name: 'Ether', - token: 'snxETH', - price: bn(1000), - fundingParams: { skewScale: bn(100_000), maxFundingVelocity: bn(0) }, - }, - ], - traderAccountIds: [2, 3], - }); + const { systems, perpsMarkets, synthMarkets, provider, trader1, keeper, owner } = + bootstrapMarkets({ + synthMarkets: [ + { + name: 'Bitcoin', + token: 'snxBTC', + buyPrice: bn(10_000), + sellPrice: bn(10_000), + }, + ], + perpsMarkets: [ + { + requestedMarketId: 25, + name: 'Ether', + token: 'snxETH', + price: bn(1000), + fundingParams: { skewScale: bn(100_000), maxFundingVelocity: bn(0) }, + }, + ], + traderAccountIds: [2, 3], + }); let ethMarketId: ethers.BigNumber; let btcSynth: SynthMarkets[number]; @@ -43,6 +44,8 @@ describe('Commit Offchain Async Order test', () => { btcSynth = synthMarkets()[0]; }); + const restoreToCommit = snapshotCheckpoint(provider); + describe('failures', () => { it('reverts if market id is incorrect', async () => { await assertRevert( @@ -111,9 +114,46 @@ describe('Commit Offchain Async Order test', () => { `PermissionDenied("${2}", "${PERPS_COMMIT_ASYNC_ORDER_PERMISSION_NAME}", "${await keeper().getAddress()}")` ); }); - }); - const restoreToCommit = snapshotCheckpoint(provider); + it(`reverts if settlementStrategyId is not existent`, async () => { + await assertRevert( + systems() + .PerpsMarket.connect(trader1()) + .commitOrder({ + marketId: ethMarketId, + accountId: 2, + sizeDelta: bn(1), + settlementStrategyId: 1337, // invalid id + acceptablePrice: bn(1050), // 5% slippage + referrer: ethers.constants.AddressZero, + trackingCode: ethers.constants.HashZero, + }), + 'InvalidSettlementStrategy("1337")' + ); + }); + + it(`reverts if strategy id is disabled`, async () => { + await systems() + .PerpsMarket.connect(owner()) + .setSettlementStrategyEnabled(ethMarketId, 0, false); + await assertRevert( + systems() + .PerpsMarket.connect(trader1()) + .commitOrder({ + marketId: ethMarketId, + accountId: 2, + sizeDelta: bn(1), + settlementStrategyId: 0, + acceptablePrice: bn(1050), // 5% slippage + referrer: ethers.constants.AddressZero, + trackingCode: ethers.constants.HashZero, + }), + 'InvalidSettlementStrategy("0")' + ); + }); + + after(restoreToCommit); + }); const testCases: Array<{ name: string; collateralData: DepositCollateralData }> = [ { From 598a9e6f7d9a3bfe615deb1b8f2bea6b8c33ae08 Mon Sep 17 00:00:00 2001 From: Sunny Vempati Date: Wed, 2 Aug 2023 18:14:33 -0500 Subject: [PATCH 26/63] Optimize 0 position liquidation (#1741) * optimize liq rewards * remove console log --- .../contracts/modules/LiquidationModule.sol | 7 ++++++ .../contracts/storage/PerpsAccount.sol | 4 ++++ .../Liquidation.maxLiquidationAmount.test.ts | 24 +++++++++++++++++++ .../test/integration/bootstrap/bootstrap.ts | 3 +-- 4 files changed, 36 insertions(+), 2 deletions(-) diff --git a/markets/perps-market/contracts/modules/LiquidationModule.sol b/markets/perps-market/contracts/modules/LiquidationModule.sol index 0151737c65..acccd35459 100644 --- a/markets/perps-market/contracts/modules/LiquidationModule.sol +++ b/markets/perps-market/contracts/modules/LiquidationModule.sol @@ -72,6 +72,10 @@ contract LiquidationModule is ILiquidationModule, IMarketEvents { PerpsMarket.MarketUpdateData memory marketUpdateData ) = account.liquidatePosition(positionMarketId, price); + if (amountLiquidated == 0) { + continue; + } + emit MarketUpdated( positionMarketId, price, @@ -102,6 +106,9 @@ contract LiquidationModule is ILiquidationModule, IMarketEvents { } function _processLiquidationRewards(uint256 totalRewards) private returns (uint256 reward) { + if (totalRewards == 0) { + return 0; + } // pay out liquidation rewards reward = GlobalPerpsMarketConfiguration.load().liquidationReward(totalRewards); if (reward > 0) { diff --git a/markets/perps-market/contracts/storage/PerpsAccount.sol b/markets/perps-market/contracts/storage/PerpsAccount.sol index 0e06e0a078..6e79ef29e7 100644 --- a/markets/perps-market/contracts/storage/PerpsAccount.sol +++ b/markets/perps-market/contracts/storage/PerpsAccount.sol @@ -372,6 +372,10 @@ library PerpsAccount { int128 oldPositionSize = position.size; amountToLiquidate = perpsMarket.maxLiquidatableAmount(MathUtil.abs(oldPositionSize)); + if (amountToLiquidate == 0) { + return (0, oldPositionSize, 0, marketUpdateData); + } + int128 amtToLiquidationInt = amountToLiquidate.toInt(); // reduce position size newPositionSize = oldPositionSize > 0 diff --git a/markets/perps-market/test/integration/Liquidation/Liquidation.maxLiquidationAmount.test.ts b/markets/perps-market/test/integration/Liquidation/Liquidation.maxLiquidationAmount.test.ts index d9a5d31460..9bd070ff31 100644 --- a/markets/perps-market/test/integration/Liquidation/Liquidation.maxLiquidationAmount.test.ts +++ b/markets/perps-market/test/integration/Liquidation/Liquidation.maxLiquidationAmount.test.ts @@ -6,6 +6,10 @@ import { ethers } from 'ethers'; describe('Liquidation - max liquidatable amount', async () => { const { systems, provider, trader1, trader2, keeper, perpsMarkets } = bootstrapMarkets({ + liquidationGuards: { + minLiquidationReward: bn(5), + maxLiquidationReward: bn(1000), + }, synthMarkets: [], perpsMarkets: [ { @@ -91,6 +95,26 @@ describe('Liquidation - max liquidatable amount', async () => { const [, , size] = await systems().PerpsMarket.getOpenPosition(2, perpsMarket.marketId()); assertBn.equal(size, bn(50)); }); + + describe('calling liquidate again', () => { + let initialKeeperBalance: ethers.BigNumber; + before('call liquidate', async () => { + initialKeeperBalance = await systems().USD.balanceOf(await keeper().getAddress()); + await systems().PerpsMarket.connect(keeper()).liquidate(2); + }); + + it('liquidated nothing', async () => { + const [, , size] = await systems().PerpsMarket.getOpenPosition(2, perpsMarket.marketId()); + assertBn.equal(size, bn(50)); + }); + + it('did not pay liquidation keeper reward', async () => { + assertBn.equal( + initialKeeperBalance, + await systems().USD.balanceOf(await keeper().getAddress()) + ); + }); + }); }); describe('after 6 seconds', () => { diff --git a/markets/perps-market/test/integration/bootstrap/bootstrap.ts b/markets/perps-market/test/integration/bootstrap/bootstrap.ts index 4c3fcbcc36..4a7576b9d9 100644 --- a/markets/perps-market/test/integration/bootstrap/bootstrap.ts +++ b/markets/perps-market/test/integration/bootstrap/bootstrap.ts @@ -92,7 +92,7 @@ export function bootstrapMarkets(data: BootstrapArgs) { const { synthMarkets } = bootstrapSynthMarkets(data.synthMarkets, chainStateWithPerpsMarkets); - const { systems, signers, provider, owner, perpsMarkets, marketOwner, poolId, superMarketId } = + const { systems, signers, provider, owner, perpsMarkets, poolId, superMarketId } = chainStateWithPerpsMarkets; const { trader1, trader2, trader3, keeper, restore } = bootstrapTraders({ systems, @@ -153,7 +153,6 @@ export function bootstrapMarkets(data: BootstrapArgs) { owner, perpsMarkets, synthMarkets, - marketOwner, superMarketId, poolId, }; From 397e1207ea0569f53675f54282263882f344ae02 Mon Sep 17 00:00:00 2001 From: Peiman Date: Thu, 3 Aug 2023 19:37:58 +0330 Subject: [PATCH 27/63] feat: add pool collateral configuration --- .../contracts/modules/core/IssueUSDModule.sol | 2 +- .../synthetix/contracts/modules/core/PoolModule.sol | 10 +++++----- .../synthetix/contracts/modules/core/VaultModule.sol | 7 ++++--- protocol/synthetix/contracts/storage/Pool.sol | 6 +++--- .../storage/PoolCollateralConfiguration.sol | 12 ++++++++++++ 5 files changed, 25 insertions(+), 12 deletions(-) create mode 100644 protocol/synthetix/contracts/storage/PoolCollateralConfiguration.sol diff --git a/protocol/synthetix/contracts/modules/core/IssueUSDModule.sol b/protocol/synthetix/contracts/modules/core/IssueUSDModule.sol index 963cd28099..0aa66bd576 100644 --- a/protocol/synthetix/contracts/modules/core/IssueUSDModule.sol +++ b/protocol/synthetix/contracts/modules/core/IssueUSDModule.sol @@ -87,7 +87,7 @@ contract IssueUSDModule is IIssueUSDModule { CollateralConfiguration.load(collateralType).verifyIssuanceRatio( newDebt.toUint(), collateralValue, - pool.issuanceRatioD18[collateralType] + pool.collateralConfigurations[collateralType].issuanceRatioD18 ); } diff --git a/protocol/synthetix/contracts/modules/core/PoolModule.sol b/protocol/synthetix/contracts/modules/core/PoolModule.sol index e7f1ce99fb..a4861916ce 100644 --- a/protocol/synthetix/contracts/modules/core/PoolModule.sol +++ b/protocol/synthetix/contracts/modules/core/PoolModule.sol @@ -235,7 +235,7 @@ contract PoolModule is IPoolModule { Pool.Data storage pool = Pool.loadExisting(poolId); Pool.onlyPoolOwner(poolId, msg.sender); - pool.collateralTypeDisabled[collateral] = false; + pool.collateralConfigurations[collateral].collateralTypeDisabled = false; emit PoolCollateralEnabled(poolId, collateral, msg.sender); } @@ -247,7 +247,7 @@ contract PoolModule is IPoolModule { Pool.Data storage pool = Pool.loadExisting(poolId); Pool.onlyPoolOwner(poolId, msg.sender); - pool.collateralTypeDisabled[collateral] = true; + pool.collateralConfigurations[collateral].collateralTypeDisabled = true; emit PoolCollateralDisabled(poolId, collateral, msg.sender); } @@ -259,7 +259,7 @@ contract PoolModule is IPoolModule { uint128 poolId, address collateral ) external view override returns (bool) { - return !Pool.load(poolId).collateralTypeDisabled[collateral]; + return !Pool.load(poolId).collateralConfigurations[collateral].collateralTypeDisabled; } /** @@ -273,7 +273,7 @@ contract PoolModule is IPoolModule { Pool.Data storage pool = Pool.loadExisting(poolId); Pool.onlyPoolOwner(poolId, msg.sender); - pool.issuanceRatioD18[collateral] = issuanceRatioD18; + pool.collateralConfigurations[collateral].issuanceRatioD18 = issuanceRatioD18; emit PoolCollateralDisabled(poolId, collateral, msg.sender); } @@ -285,7 +285,7 @@ contract PoolModule is IPoolModule { uint128 poolId, address collateral ) external view override returns (uint256) { - return Pool.loadExisting(poolId).issuanceRatioD18[collateral]; + return Pool.loadExisting(poolId).collateralConfigurations[collateral].issuanceRatioD18; } /** diff --git a/protocol/synthetix/contracts/modules/core/VaultModule.sol b/protocol/synthetix/contracts/modules/core/VaultModule.sol index 4045db1586..4b5abe407e 100644 --- a/protocol/synthetix/contracts/modules/core/VaultModule.sol +++ b/protocol/synthetix/contracts/modules/core/VaultModule.sol @@ -119,9 +119,10 @@ contract VaultModule is IVaultModule { if (newCollateralAmountD18 < currentCollateralAmount) { int256 debt = vault.currentEpoch().consolidatedDebtAmountsD18[accountId]; - uint256 minIssuanceRatioD18 = Pool.loadExisting(poolId).issuanceRatioD18[ - collateralType - ]; + uint256 minIssuanceRatioD18 = Pool + .loadExisting(poolId) + .collateralConfigurations[collateralType] + .issuanceRatioD18; // Minimum collateralization ratios are configured in the system per collateral type.abi // Ensure that the account's updated position satisfies this requirement. diff --git a/protocol/synthetix/contracts/storage/Pool.sol b/protocol/synthetix/contracts/storage/Pool.sol index 8552ac783a..06de09d511 100644 --- a/protocol/synthetix/contracts/storage/Pool.sol +++ b/protocol/synthetix/contracts/storage/Pool.sol @@ -7,6 +7,7 @@ import "./MarketConfiguration.sol"; import "./Vault.sol"; import "./Market.sol"; import "./SystemPoolConfiguration.sol"; +import "./PoolCollateralConfiguration.sol"; import "@synthetixio/core-contracts/contracts/errors/AccessError.sol"; import "@synthetixio/core-contracts/contracts/utils/SafeCast.sol"; @@ -118,8 +119,7 @@ library Pool { uint64 __reserved1; uint64 __reserved2; uint64 __reserved3; - mapping(address => bool) collateralTypeDisabled; - mapping(address => uint256) issuanceRatioD18; + mapping(address => PoolCollateralConfiguration.Data) collateralConfigurations; } /** @@ -520,7 +520,7 @@ library Pool { * @param collateral The address of the collateral. */ function checkDelegationEnabled(Data storage self, address collateral) internal view { - if (self.collateralTypeDisabled[collateral]) { + if (self.collateralConfigurations[collateral].collateralTypeDisabled) { revert PoolCollateralIsDisabled(collateral, self.id); } } diff --git a/protocol/synthetix/contracts/storage/PoolCollateralConfiguration.sol b/protocol/synthetix/contracts/storage/PoolCollateralConfiguration.sol new file mode 100644 index 0000000000..496eae7316 --- /dev/null +++ b/protocol/synthetix/contracts/storage/PoolCollateralConfiguration.sol @@ -0,0 +1,12 @@ +//SPDX-License-Identifier: MIT +pragma solidity >=0.8.11 <0.9.0; + +library PoolCollateralConfiguration { + bytes32 private constant _SLOT = + keccak256(abi.encode("io.synthetix.synthetix.PoolCollateralConfiguration")); + + struct Data { + bool collateralTypeDisabled; + uint256 issuanceRatioD18; + } +} From 3c89ca90534bd394b032296169232b2abfc2a7dd Mon Sep 17 00:00:00 2001 From: Leonardo Massazza Date: Thu, 3 Aug 2023 14:24:31 -0300 Subject: [PATCH 28/63] bump cannon version --- ...lder-npm-2.4.21-5dac6deee6-e37889a5e6.zip} | Bin 1298271 -> 1299563 bytes ...-cli-npm-2.4.21-6e52472173-fd2a755e2d.zip} | Bin 209555 -> 214691 bytes ...nnon-npm-2.4.21-73f233b4d8-f00a31c6e9.zip} | Bin 57315 -> 54865 bytes markets/perps-market/package.json | 2 +- markets/perps-market/subgraph/package.json | 2 +- markets/spot-market/package.json | 2 +- markets/spot-market/subgraph/package.json | 2 +- package.json | 2 +- protocol/synthetix/package.json | 2 +- protocol/synthetix/subgraph/package.json | 2 +- utils/common-config/package.json | 4 +- utils/docgen/package.json | 2 +- utils/sample-project/package.json | 4 +- yarn.lock | 54 +++++++++--------- 14 files changed, 39 insertions(+), 39 deletions(-) rename .yarn/cache/{@usecannon-builder-npm-2.4.20-c88eae7630-342818635e.zip => @usecannon-builder-npm-2.4.21-5dac6deee6-e37889a5e6.zip} (60%) rename .yarn/cache/{@usecannon-cli-npm-2.4.20-0858c1dc0e-39fa135e5d.zip => @usecannon-cli-npm-2.4.21-6e52472173-fd2a755e2d.zip} (77%) rename .yarn/cache/{hardhat-cannon-npm-2.4.17-e95edf0280-d854831f53.zip => hardhat-cannon-npm-2.4.21-73f233b4d8-f00a31c6e9.zip} (82%) diff --git a/.yarn/cache/@usecannon-builder-npm-2.4.20-c88eae7630-342818635e.zip b/.yarn/cache/@usecannon-builder-npm-2.4.21-5dac6deee6-e37889a5e6.zip similarity index 60% rename from .yarn/cache/@usecannon-builder-npm-2.4.20-c88eae7630-342818635e.zip rename to .yarn/cache/@usecannon-builder-npm-2.4.21-5dac6deee6-e37889a5e6.zip index ced975ca0c55e1571502a580e3c8367f794e77d6..ec2fe3660ee244b5d1732243b65bd91fa8a01e04 100644 GIT binary patch delta 532889 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 z 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 z zSW@@0rSM>W$P*@#RSlMf1(vY|mUFZn#O3?h%)fJ0Q*||>VP+=EIu5e%OX|)0=mhx@ zw@3vZm?@)Xa$r7So=JCZ(1zIzH{byx0{{zTfCT_)02<(Bwst-22gZ(8jez`o*;n$r ze;heIC9&EKy^VwyReGyTpKkAIw6LeLj#WIAF^CRyqI4Uk7$vwbLuSC{0qr+p!g!UY z2c(Q^G0g3B0S zNuKk*+yp6_VB3(N>DzSqYLq`5m{S}de|pv{ecM~Avpzw(Bi~NKe@2NF|dzHDO|O@xWoc5%AJ5lH(~3T0p}+%NvF|7gmQQ%*VodpgVW22?b=g z)WyU6k{Y?hjrGDL-nm9PG;gTOTAn-CX_dKc{0s(PGJY;`W4#8}?p(1ca%0U1%y+I6 zGed0zo-sq}!is6P+_C1E_tuRae>Ge2&Xt-XcdYpfCL^vOiyK=|DCW*}s{$n>GL5aS zzT1}^7)dw1_BOC(-|g>K5(7wmRmr(UX_cH?m~;0hHxZ6tNPSaHUgG4pm3o&T5uMK1 zY1h|~xbx<@o4UM=sn08^9m7JVS9o1~7XKBYtwQcny`}y}GHpj^`be|$c6uTTb+<7oHf1U8U8^T-gD7H6(1DBXF4nTl#Nl}Sq! zRi-XDK=(ig>a)~UR6A3hS$8_K#k2YOhK2`MWe+(%-8Pji^`!V}UgvsV!}`3UMY3c! z=|!=VWL$mQ{At3itk0xue7a~+s|$+PQS4oWboDJ=z#?VOYHajhe`t(+U)U`Uj#^F! zj?kTzJ>-)+_98-#B#0KY%M`P0iL!Ddi}oC4kuV@Ta(c&(kk9St=E)`|$lW3ies%I4 z(I!`FhntZuw=OpX`R&$rJ`2Z6H+XMGFqox=VaAIl1bKCLPS98^HJl0W0v(W4z|uPDTSTrqUtg8 zd)a{We#qRJZ@%$nDYemSw=I|5?abjU2G89cY{P9)gIcb%3V@E`g6;$fH`W}*s9qfj>bh0Bj9>(FMXd=dZ%|X-A_X`> z&tFlgFMlp|e@WTv=v!xl0>z*NycVP|a4~3MRWt7mNnG8cuzgfvzqiyyt?lyif?5{u zA1yI8!!Z(lowh(oU$0M87R1_ErZN{_DoE0JRwgV!wpvz74N+=elO$0EJk@bV;Pp;@ zCa{tl9FE4B+zauE+6m|ORymiS0gbe4*KW>lJiW-pe|>G6$WsZ?lDZ$N@-^&}1r+k4 zd3Gk(v@a)DC)|9Jz4NTutqes@oI*4gi>AV*;BIG0&^3d)MOUOjVojKdNsq$8o7j>o zQUoUgE9=GR&oh;0f;;I*A0}l$TnIgG-MdQVW2e)w2u%?9xjswSu3rPkBGuEi|3%X^ zO@Z2tf841ntf|YawE>pfnY22T$r@ZnOcRXIlzvea{x`r8`)NZXynh`qLct0w4i_I_ zH7HvP2PNM9S{c;f16Ka^X?qQ1nx22KeO`5l$#H2GS?G@ zYOwJP7wQy>tPa@6Pz22F!a{}98%G5V2T`rqA^{8?jv`smQFG{3PRv?gGjs-iL%C#O zca!Vuq^abW9ENAiRR33uvV(L6L78bD|jkJ95-2kpjU;S7X$TLuYP$sRu-&zIs+yn3bq^SSYAdVG&^9Snx&>r zWRlOctCC(u4Q8>(PI_5W-2nb6aC^Wse>F^iWnGzR>q?oHvGFY3>55qTZu#?e?#;-4 zsx`2;HB!K8XoINd$tyf63Ef$m34eB{MPJd2Zc4tfz^%!wv&sHbn|dxqX!>%rbnogV zLgi6uv~~@CQ*0MGHA@SMs78ua<0Euvyj7}v+WMj(0k5>aXn#!T?2^S`M@j9Ue`Cf$ zI#JeLcvsTQiPX((f_tGNZTzsPfNdY)SVvga z2sf6c9B#?sI65)JrV@wP(=V-DfAk!+j4jLZa-sz92GR~hzHR8~>)3(iY^nsL-K7LPs1owdUDROB;fyAfS)c?g|1Fv4 zUSTV@R(GC1r=lamtmep)h{e9e0qfeM8<42&l}x=``KcztN_Iwzh&8e-fBM^3?L%Yi zagd1kkZiuS=&FmZqY3?@jk&Vr2aefGpygQd>&hg`RI6CPP4v#LYPdCY{nyl-uYTu3eZSQyXW(3=A&2WmnWXzS5ZETO76<% ztY&WWjWKN{Az14;9bdLCf8ydaofoY(`WND~Zyd^)>`7jp)ORf;yJIN1$2Vk~KpyUA zB~yYITIHO~1Y{eYC^?*y(ac;#Q&ydV7pbDf%H|3%mG7cr1wQ6_A10HC_YVeM2|U*{ zr^0=^JJ44Em^Y!63X7o|zwpp8KW;?fc|cvnUXDRk;PYDq7VbtBe?8pRl7cP`z?wo% z8fdFTixIr`FwC+x8q?XG)f3Ym#%+PX&!%E>HyyE2nyw_*84l1w>F@~fpO@Q)Lhcmo zd+qcDy+`H^v+y#}vvB9d;5jmzjEbZeiB#Lik*oMqbB(>0YW`2rW$vLo#6N~y=e*@+xH*nESIF>IzkRI&jj3de@PyNb8?45oCDk>}m6mE_#qhm|5 zdJ{&GxV@F1l5nRRLSJByu)RPSnU)evQcP6D3to4prO)epPqTXYlVE%4b&6` z`{YA@_lyw$uEm=R;d2E0hDAf8%yNMUz|lG6o*Xis*`=M~mvrkY=G zKoUbEjs%XkE5rXqD=V$-wZ3mLAWZ_F>L(JUSRX8TqoH=;DAqt%g+>M95=*F9I5ZmP zsJ^;2znW?lpu!z?1COKXB9O2TIN&~!mU7NKzhO}cW~uEPZhu`#P^Gbuqj0|ZhmsZY zb;(ahJ(<)#!k#ONr?zG6J}53Z{#+A8@%@%mf_8FAYsYKSDVo> zov-!eQZn-vt$)m@jt`YO-oCf4{=PRr>#<*qERbvl&_IcP&U#G0yhM_naRR<1&dth~ zw_jU=O3*nH&=4gVEZ;JU4|vh;Ia*IY=Zkhf(-pg=|IkvJ{7IpBVpO~~P7)BR=>AN! zimvtHXP!rha?pkuzGD?3UPp^oBlV2!<@>2Lk)B1_Bwcdyg`?A#MKr^@k|-aAXVDLN zn!HQnq#);Wi_>0Y;e;aZnW9z_InN8ZKf0@8jte2DlZ|aQfe@6v3qwWRZwa}X6 zOd%!X`gHaEhgZ9MNQYje**NdlWOXsg=1$Sm2YhbI=wXHsBb4QSkNx{9bUP;k9CKY?PaBF(dog+CR zuVNxQX_?^rglDl|$SSF=Y2!e(Kk@pp1+N6j2&{ny(^i3JOnt{UT}^M;l!Ky&GiQ&d zP%#^>uRSgKL4qiY8JnSliF9o4U>H9}78 zv*Uo;8PagiJ@+`^$cOhY@h%har%9ol3EW;fN@`_Ox3qoCrK0&rME?o;)T}Lc)v(I1 zLpu;CEaW4$Q`8P+y1NLd%0Y*6f1l!RMD#8vxdmX-DzbUhT3%*;2orROks}siTv=rx zOCZb0uX=kYw0~=fx~=Q$7NQm@tuta5nG^E}>V$vflkY_bgWoa$)m27&1GiH>?}q*e zh1X1z@|ciji%U}X&KG)7uT;9{2VM&$_1@n&=d})76W&?wHPuXk08LPAKGb2rB(qv9~{Lu8ZQ69^?sfqfWiwc#h9BPm7R6yGK z#E@*K(z|)YazKYDyCUg02?~QF{?fvb*X&N?NDjTmjupt55XPUTlS!1VUWBMmBcIob zj&AgSB6U-&3S;vZjE8m7e=7v;h298wBz!W)ooH%)_hfS}SoXtz4d zK6P5{!}d{+Q@^p3zrl2w|GxSlbLw}Ocx+XvMyyXLs3XnrNgXfC=RJ@87u0ibMf1`!BM|jccg#9JJLV>4R@s3RETGm?lk9epXblg zIdRtP)s=i`?y|X(N|JAqrM!m=T}k8DW}f-ybCCo;SmTSCe;H9YBVrW|t!x`znAt~> zcGoU}f=@fNBB>os)vRy)$b2Pq<`swODHkwqiVz3#63=|#y%tfJM>KNKh63NqpkvWV~T*~eo z5!1CQS=6O2fAL7pf&kT#=ivlS)hi_rh)TQ!g9qOcIr~6QAIigm%+os8T_Fm(zV1!+ z%E3}>#ta+D2HZ@ga^+%#s0QyIqCFpRd_z`r0WZBvONz!BK%xmumL z=uOKY6SPbtI9`EJ&w;o=7OQt6fE$vC=(G%`VjQ4nf4>A{;d$)QWImYpPOh&{{Xy)F z#Mtkp-c-TY7~#w6m)StZ1DMEaowK?&FN1=+Hm!7RWOePN4Ceh9+6}Qjfp=v_*VoXi z)SHVMT+1F+cDa3?qxZnt-eJf>z`A)CE>(9S(oU5fxp2oRO>tId3u>Df8^Kr%O#j(P z%TYO z+7W|qO}Cv-gxp>7BI6TLSgqEu{zqIRBvYw9fBgZ~AjkQKAh z&=#)Wkx1F?zSh2L#AEv@lWBC+YuSXI!6Y;N6V7tyJ15~cd8iU1cXC)C+Q{TEBDAx} zG~J7a9%$-oub#vHfE0q`s}qfjB;pul5k`$?W+$zk(p)XEWWyka7WmBU} zYpNv17;SzJUC*8vAT~w0n_{Z^qSsFDf9`R4@9GSi76)dxQC!?P)Oc#wWKV}UJ@iXj zuaPg(Rb$yUlF6~-1ocX9SUBLtmBS~*+Lb{X!~?ZkBNm!v4!`GnF{I!Tj@+V;vU&*v z2MbWe9WhGkAKJoUi)sLvxN`7DFDYRJ*5b$RR!K{~yAc9_Cp|Ts1kp`o0t?1~e`mr# zqoz9z))#s?84VtmrS}4La4*iwA9M)Z;P-Q)+M{DKEk0h%5*EjcDe~eNJHt|6c#d=Q z$Vz;;Lq%uD%F@<5P{L86B&(v0qQeP2DZ#4X2#%u7AOjB+C%X;6<~GydueatGcX>HG zmTm=0r^l8n6Qviv;!gFh3X0CHf4Z1q{@%f1DY$m^U5&+jr+%u>+-d784@Z4ggVWzj zx$yKo@3Bly&JOxtk<){ZI6t@ss_>O*1dem+w)QuR#}W1f%~z?(LxHjWdR7@A(0Tv| zN;yXt+1ahrv51cyzo_Xk`x;MclEFAulmxK(o_l+xKx{f8SfJDrV3p zx9k(jkF0w+45f4_bXAi#i=0n#^F^?2SB!yMv~1-Vc++O^k8c3~_;{5q!an3g=>~QJ zdDo;AM-}oS&8!U~7JfH`p*(*J773t|!V*rnQ;&9mo*=|&(bV|MIcG2d}e9rFKGNlfAUazYL}ipCnOcs z6J#W#_6#B1LO26Q(>dB%$*{Vt9;55;tC)f}H~q$e_lUca0d~gmsK{HY zK(BQYqS=pc9Qr9+8r!x1;s(BHt559~1xKYBo}2!hT@By$|@wA9Cy5BXIXVmqzJU7sKXL;GY0GuJN zhV2~6PEjX;8Vm~UzykKYhohb9$?TF9ka{Bmq7mcx*g1?EK+Aq&cEku;OrcFyCcL4u zB^NmZpWja`uK7weJ8;7oFP@+rCnyXOG&g7QG4`b`Vjw%^e*unHxlxm)GV$2QoX0Sa ze&0-0ZcotiGIcQ~LN-L%Tk9J>2fslrmAm1wF`t!Jsp9dmL{~DWT8xznt}rcO&W?PQ z9M*e|jq@Dl?i~7+DyPUF!vFeKf2UOqns4dFBUGAZzSjggkqtV|eE7@DXj^OWAKiY) zVb^fD=TQjze^OF5J^MsXR^??0dny%;gc?Vkrsy~`FH@SAHtRoVR-C$0OC(w=17oH> z$(HWWC)GZ8%BuYTw4DFJXHOTBLspBgf8kq)z@pl-4v&O8r-;~Fd-rwSyF>plVTk~^ z_0LwZKF2Uf32wNlv~p)4S2by9XU4EbyJ6^ z$AB~BsB{A)hvO!AZ}b+dkeX`))CSV)i*$#TtuDp^enpXMnaHb9f~Ll4`Rz?cK4^A{rYD2Cvp!I_A5BgfjT`Uw2ZWb4&a0V z=BOSX1z?Fj-CyC%lEss`sXo}H`gkZ9^T=GZfp4o(WbAv@ zCajHhgdPe9m?6$zAafVVVf45z%M@^AF1-TyGA$}^eaMb-2qc+_9aU?0>d>21+Tr=~ za#_eM^73*hd1NCKsP=fttk_W>XhfnbflY|{CU{Zu=7&iW^3FPEF>lO`>sPK!xrL{( zfA&Mk#4j)FY;xtD^FIde#m@sXy}8hv#N6M^%PPk;6*Z=8q`iY%iZRK1lD_T8D7|oO zQif{sIC9bgOEd&D!%1TC2USxZ^_-LfQcB0r#jqtcR)z3f!Q^D7#nebp#=OL?4WLh^ zP|OslsgYGENgjW!)=12dd_#*BtrJzse;HQ_u4d+{M7bc05kU<4lh`^x9|*z|RCQLF z{T7#*_=;N%$9`KQOh59eZx&j#SmjvXWI1*T1M{$V&pim-vb zw#Fe1pN@?c;G&#Ir6mcwJg(eWryA~EQJ+d$50674u~OZXoE+DE0La1x3ynv|uHg_~ z195e4ecQ|kvLlGbf}aV$>+S&?e;S*%XU>cbY}4Y%xA|LuO`3+`u)U<2*~Kfjh`-Kw zcP6;EVzfudkbr?1KwWns;-;&y+R`(JIiStyUCm5eL=EZrIx3M4MLjLa8HkngsB;It$OpfSi*Fcgtl=fJ3kJUv^H0MM%grf028Y-7;}E zj=87~RaAE1*|Df?(o0IKY-N|-|1vmSS^$S;(8TFz_`@@UdRjv<6Y5$MLYmQ+8v1IK z%K$_d26D4tdkH#za$L8%XNgI6sMex}F{?6MIy@XeVTg8ghKX?0Mn)%=(s`1Xc!vWB zZ5`-is%9!8)W8TLA(z}of6&ZHaBy&XyioB4Wi8FuqKv73DC}AcJ0WuGWl<)L8S{oj zw~#Wz6AfvHhkbeVUE1Kmd@V1ZNZq4Vz%|hm3%?vHBZyN4rz1wMmaY;`=_C8n3gW|9 z&v~d3^PEbaBDt!+d7PkFpz~vH1{tCE(Pa1Y*%6)X$Cd)+LaJAef3CQ ztZ9&O#SEo$GVzwzz{Ds>J-qNT_50*+b}nsPB*<`O%gbD-lB}dPl4VGw2@z#Nrvj__ z{FpnZ8HA~g*eKGBaCPQrDN{GU0W9Vs$g1TVYC%uXG!m@N(K_N~^Udjg#vp?;4@XE5eJ%!t#}@>Kxx9Hv03gTLbSTEyo@eV z#IZ*}nJYre=Sxmn#iFLVW|2^+B|<$q07>4KGE61qSVi|DRQb7QEfm@$0_9@OBg$m) z;)A+xW8HrM7NcgkD`kJWf5ioPW8!ElT*t(HXi>Oh&+jp!AUqTXJQw zlA8%$x=&o_Jt^D0)=@`7bG{GYUTalhSGrw0O);W)P*i(X9XKp^M?j$s`t6ts7A--DUjw?A+`2_JacYJ<}01n!+?Nj0JgHF4#e^_yiPd16xUEkE3Ha6#W4@ z2RzH7>uZbBD$(g@nirMCNC1wCY!m!XT3jqBtgI3!;X%}JN+-2bI`P>xe;3Zch@7{0 zZdJ&4)1BoYIT(@MoLj*O8TitRn4ctTK{zGM1}o1?R0$I^OJ+qLlJlI z#_NdwoX9wRp!1dt@?wjaLl1o!s$!8#lN&Buk*tL z8s>$-2;j5HXXK-pZrk%y0&F0vMq;8GX((tS8fOl2aNzf3e9ft=!v_CGG0Run+Q+ zZ_!?q0H<9*UU}skSEOjurkd0@QHIVuy&wTWyP89Tqe`DW4Id#OcybMieCRbVaCr6VZ zL-nlH-CA8~zgD(Wv+jMyah;A>dcz~Ye${(`!7a$H`}47Oz2sBK3xV{1(Fv%16wN{X zP_1t@VNBnR8%Uxxf;M_FxFWp(dHoGupd8h9t#%e>xgA*GH5N=P!7C*=o?@abrZWN+ ztQd$9f0&AYwEcs%!w&qGm1E-Nv8Wy-ua9N>e;fz*|MBtu;NE=$0xw)k1mj}wk7JCG ziSaQi=hO>o!8*sPq`JD-frHN^w}5%+P*R}%9QyLFgK*`q;o-pw{H(1!SsfmJd+&Zs zC&?>Ixpz-0_g-n`-s|)JtHsK_*Nfe;h}Y*he_N#YhDW8@_*~$dVnScYhMRPEt`z&X zbJe3i&ilWeFYM7DH}vR_^HszTZ?oOmS#c>n(?Md9o;|IlS9ZrnLk!(=+;QN2iN3rU9kVEIb=OkaCf8MqY#4@roay1SWaYfGX6tVz%j`|2&2OYc8 zm8sN>$lJY9-E$+1rlFIk--SZa-vuZ=Ulg{XajtV#AQTT1^ZYgLsG4`Aq8`I zT+;1AG~W<;1z7hrunv#=`-_2fcmuEwkEJ4LPf5?nuU9>pPJ|)zYbtFqVC#Ol`7Q0* zA{m{=PnK3cuc%oUEn7OgayUQ#Fq zAobIWX#9=ks2^J}_XE_mH|v(H*^`5-rr}7Hr*)lv;U=w{GGujA26X({(=8!4_*IQH zCC7K~!+q&!)b$A}eT|m(?4=d&GS=4jWL8!{j%e~Vg*IiU-j zda1Q9_^W1!b0Mq>fMr?hTLiU7nFUyBX5dQMxHEix13P=c4zqnWi7Tx;h+W-5%4Y!| z31nvvd&2P;Qr#1|wI||5dxG5T@ieODZrl=nK3lv-r^%*LF*iYBg>nb zi<)g^n?bb1VyGm?shRP{e-lK~p+#=FymcH}q+-7MN3N>byG)AkGuD(f*nP>fDW=a> zzk`F-)zz@E$f0wO1gLx}7eumxSJ8QdmreC^rz^kkMTvt$c8P??re#Yi*;}VYS&J-A zB2?;EV%|k`SlWy4ja--85xc|Ad(O<~JgY{d&+)u0z=B-~6b>buf3Am(@ch~_hl<42 zAI122oR6}27AJUTs#gd|dL0#^)DyY{Pa+&IKC$KQ3;mqf=-!J~ow9(S%^+g_Zq)_Q zX+EdybxG9?*a^U`+SQ=oMAcao&kX5o4*ArZBXfZgOEE%O<4MJ2@l+{+9je<>*cr>N zgf|Ae4r0YDMRAJAf7FbwX_NCOhvX*ptVv?0m;k$pB-OR4I(hKJ8rpN@REW@PV?^sQ zDb(;rbk))uwso~;T^&-`^F@xb+-}M~t=egJfs$N$xfNO_oOh|tGUvRpGHo~fWtD21 z(1yyjeeqqYRGG1&!ZA9oR$H++zDwn95u}LyyDk?|+PAEMe|2U2t}}d75j}4%Jb%T! zT+vYJ!f330Ri>EKyM604crK?p7Xm8^vRVsZZ_x)0KW+vM4MDAI==;)4!vMSFmaQyy zfF8|4v~w%zx#XkL#R76_c*FZ@o@^uMu^T(6$-oL-=rGQDIo5+HGHBxCG#+Ikhs2<0 z_ON;nP6nhzQTS?}kLmVYlbaI7{2eGa*m{%&ofOAmjzT`5Fs7D_&-Y~Zc^1FtRP>a@ znbC}@#4DkWqgt{hkP)vw32rgxRZ^>(HE-l=e+!F5*|H2HGV+{PYz6)PIm}{; z@)(wtg!Wx{8_=YaSJ+~-ENpdNliBzz!8CWz>}#B8Fjtgc8C%6fjJPGr%A_Ii@{(>v z&aQRO46~yNM?D5bZNVH+D=I8O#z2?wI0^QORTRIIpAZt8C`Iuvz$p+`qjsA@THrj! zJY*6Tf7s5`kFe67vgS4-nOF-lEh{*VZi5zTmJzlJcOoGc$QmU_xPWg!hc0!|)vyxD zD_Yv}@8fI8_4^kjwpe26QKM5Ex*_X3fN`woAw&0A#8AbkQf+6O=~g?rufn#NjqY1i zjt#=NFr}JG`0=Fo4ITZp$-$wi)v~HKZuR8He*?1Fno!oL^t${mO|A> zUE>Rxf=q(dY#-UT)h|f$6dM|49@!29vb;< z7w@|E^3lW}vGIuRE)Tq18bBrPt#4mu5GP_>@lE54edzVb7q0&x^biCITnr!{+Q^jy ze+%o5v%b&lQ~2LpdA0C+vewh_0$OX35vN7gu6UikSPGk%&ZAF%D zB@~FoRO0WD)N`N%O80D!V9FZ>z?zAagN&XE8Lcz)?J;L1M@{!Rc7~j88W7n{Qm*P! z6;`NgZ+*!?B`jEjm$Kz$oHgQ}Di!1HE=p?66LLX_6RW-Ma@Xu2b!M)Tpc)p*f10_N z#mvSbi8Lr^QqQ=17J=1ZYV-mn@kGIX$b-~!ci7MLW?ZuDJcoEi!&k#Tl2?6O3TQGL z7*H$FvP`sNf)8|5AncXrnGm^c*m+g)K6S|+9(_E``xEbyED*`Kvgee;7_L(9e~I%( z+u0hGL)PxsovLZsA0fsoOF_}ge@i^WbDGq+qDvqEV`p}No0`W#5MRh~G%ZXD@V~r_ zBS^H@-o)y=YN52pFs$glHGJZJw)RSaJX6DlGBxeoSd%JHuS&LI)wC-&QYSb<+Jmr# z!F@~uccO~SxZUz>JV^exM|JfRo^TClvs|Q&Hn$sZW*utOoQzCJV1Wydf5C8gNo}^F zsIU;?)*7)cEo;)s9mHggHq4EID36_n*=RQ?a?M0pU+C)l&yyxDJj?W?># zw1!eu%W8Xhd6BibBg>+JT2Y9M9lcI!OZEaUd#SV|Y52}xtn#JeZ7H15k#LRu8?v8q zzKX!XzqNicXu3oFG3Tq*e@`=g-V6)2RX)TN z4mq9fo5Jp-Uz{}NJowEj>AdiFyJF&V0*gAf{UKTTL}oSX+h6EnU}3%RNBcIk?!EpL z&T{fBj<0bcBR1ngf674PvK_0LXDXJj7KWV5_yOXnXNn+|qdCE9@#?sV-A${v9DTc- za7U)7P>DDiF4b{pb-K}JJYu2GSYzVg*>%!YI=u8erW?CG1Y;-4Bm4x%tFXlUvPU7hi^XGe`T;OB5kY+9*q>$S@%WlnBZy* z#DBT{xxTiCj+fK=mAP`=BtJvEfA{#tC3nEbi$ExwkoO@q(sN_T8<#sXgtC5jf+ct=gmjbjvGsv%)md^qdw6_!3$mvsJL6Mu5}N`Xs}>5 zZ5vrg#XuQG;2ZMuc2bL2=DlUGylZTD}jm9uOdXOSMJ_ zr6M9l_{S5RGnv^KSgRvQjSYl-R=JPV;5$O8b)a;YQVnN-ddy!yIg6X^9{=Yun_XfR#fBpOL`rm8U z|L*$V-n%b8L%Mgcw({h#<9q+Ou4VC^f9n}f(XvR}R7sx$e5*8b49*f68%bWkYqxD$ zuC9%zJohORMlT@z_-?g`ateN4quyUi4-`nSubgq%a`r`w4ll^#L4(HM^460FpJ8K1 zBk4GJDgVMY)IIo4e$XZPa2(_Z>xZKK4|4E80|>W+Iu&wa; zE8$^Dg&WH<(hNDgLmFh1Uo0te^j2DuljI=PhUu}oqjSGqi#jm%F$i87C_S_!J00sk z;yD|l#FI{_JQBGqooiqA#@Sl#geNd}agLsGtdDSnW(pj1nHaJuLRH?HpNZCJo{`%V zN<#S?yY(#fl^cC==BapnUe@lmf7Vnyi?!far9-a2#K4V~VSz$Ngo#9q*NE_977%!7 zD}L2(qxD!Gyga5m+;}4*M5bB0N>{V-3~y3h$&2E2rP-6NLdmtl4c7}!g1l3Z<^L() zaI|bktTRt{(l(1wRugm&4f}oyEa554Ne{X|SC{G-)JAv_Y`zMFGCp8?e+gF#hjfm& z>=s1lLYqK4XL9I^x(9**g|XKRJ9Gf>HgxEOZp6{XLB-_2!+aq$hbJWd28te*-3ZW8 zoNc-yuiw=iRWlxWe!LiwXje95(j%kK0sxQs+9`1*NB`hWUzYV2_}boSVCRp>o2WRm zlUDC>3$%hj)rvf4;EhG2b;YE|!;c`QR=`Z9>vU&rD*H;CAe@*><{`ewv;$Nj$+-;DU~_=dRTB+iRk zOl{@dU01m0U*&VCNRyC+R>;$1+h*=_C8h$xnPJl85Adkhebr&~e4KlK>DKkomzc#Pj4-xhlv$n|46+~S7eO4lB0(DC*4(I`y5Db#|s%t{h_b&{pC z7QluKb;>jk>ksiRu)N=945*mKaq>wipmeRLZ&>=CvI$pLII(o40rZ@sCrD3h0nB)PmHZe)7Xe=QR4aB-g-IM8d83wr(7{mY@WavvPL?Kg%9$Ky;UwFeTrnun%Ivpee|P2CrtLkci30+Aarzs#kI+i2zEI}wDNjm;W#+}qKLA7ONRB6w#MYd-bwpC$#VPjc# zgP?_DeTzr@?YIKhO-HEUIaRYJuA=;5FA;dnp6nh?A#xmc<@o(pk^!b3_=dqR$E!%M ze-|Z6h7GwZf7Oa=ExwF*5^3{AFAQ>rw- zNfFPY`vyl2rF20RKPr6_Wm>lP#yArLc7*IgY*kw@*W{6K!h!g3{ zVBS+$0vJ#Gt`^Tt#c0sp@z>YZF8ZSw4}d^M2LYB7bb`fp`$&3sG`oY0R^heeYp(qw zyJT_Ze~=M64JIc7mBlmBMWbPY?@h^t<{7{?c`9&cTc!It(qwM?IT;1W&+ytIqVgo$?g6chLrtId>TJcC!60r}EIlxEQF)5e=vFzxdDzTr*w34RRPL#%kM8qQ`H8^ zVY>{et9j{Lb85S^v+fb+U(ut@ci1naY{9)?agfpg#A^ zC9WxLHP%bpu5u`;jHGp(f0)hz}|0v8%9s6i+ZO>^I2ks7Q<8+-)I%E%pte+G0o zbM5NT;0Hry*C(OytA=o8kPAzYWfPxCP*`dq6xyi8br{3OwM8K}zz>{M#f2Ts+DOcB zw*X$1)I)5AMQ~>(2L$0TWW|N3actRzaCy3_Qy+5g*3a(T|H9m{z{>*!G8s#5bp&*R z_cTadu*iJJ^G9mw1!N@i#O7-3f9U0jTIU4qfy}Dp)~fVl62VqxHa0VxS7x@b;xd|R zwF5n-AhG+O`bzaAnpx-gqRwRJ7fQf=VLALdvmKe$d^Q?qWVYuE zQ06)cjTY4hxWutk3?SpGrW@DqL^(XLW;<519a8{gxjkz}@v7)*K8;6_f7kUb0r>(! zapsC+;SfFmxcl{3%f*fVg~UJXH`%Xf*sGxgIE~O%*@1yua|doIydViJnl8uW!0Ybt z9s`&VK=00iHp7P!2kXC!t}JxAFMuD?Y6v;-&$Ymc3alJ71wQxOPId~~( z{wI)agt_hmXhD}-f8XB!Kb5N;OSU<%#xZCjr2GL#L6}YExJ%V-9#I4;V1dYjwSKl0 z^|MaL$5YZ|mdAv-xB_H1-k-uh5{Imbl`bpS=vdNsT2{Iu4!Zq#E9rMSv5&4p1N@^< z4;52lse=SRCi){<(DHQvXh4_04=cDmv}wt_tjm|)px5q1ownb$s6%f{1z-@;pslTN z+C7O=A(7+eF7yv7LlkIa*=qZ%XX%-z6AmFEKaEdd%AwG!^dichg={)!+`HLf8H@D8 z*;zePYM0@Y0~UY8ouY@Rc!@9!+ZSJP6oZ54u*W7dW}GzXYLFPz&~jH#07kKA*t2_~ zeM~2G8^F)h+G#4@6c3eelHgI=|#A50<#EIZRP=A z_RoXe7ZD_M(oXxI_*eh>o%VIRLs=d_QRSLG^DF8j+XsIiKQ4Xzc<YqQO*XJ+z^~J7g4fc(fbWDRCZWBIq+TX$?;uPjI5rsDrA?4}8 zSN_~*zveX0>knZi9#TP`wsm-a023PPlrFqjuWN&YF0LIXtqs-&_$W@HzLQQHdeQFG zetj{9&#*>UUGboV4xUl#WBd*~cg&Ta`r^_~htz+o&9dD&^Th0r3LK8f|NYy&{pP%kP3k4y z?d*TwT;jf(h=vlwH*XgVNENM@`{~2(``>?>@^el-^VS5K!Y|(MeD`|y&HfjZm!)_2 zp6$GAoOsi{4{zS@!c70X``peq;*W3lzu$d7eD?j$`@My&&t*mLp6w5J-#mN!+^s3+ zuP@*I{9xz#b7;${sr@ex5D-ApJuPe+hk-Q-pU6O62>i<1~rbh?s6S=PV!h#S(_9k~9Qr zMEyQC>G!3$6|G6I3uzD;F(`CkDZzgTe!NG`6OuGC6Ui7@Qk!Zed8QuR0Fh0;>b2ey zK32wu%Rz`Mg+&8u^`X0a6eyKw@73e7xjXr=~A$9gVi&_Z~{Z#ky)X-eGY-sKq zRNSdlgMJxOy9m~RpqA;%=DA;NspozHRCY#|J;tiYObJ(v1`Q}phI4hj``~}kgU1`2 z4<5lOy0HmoXBW=N^-VYwHy*>m_h@Ym&b3GDa71<2AH#9eUTMP_a{phSla-bGa7f&T zJpvTO=SRDT_u(kGfAI11`tHa1#@gCCQWa~v_;<5=cz*&Xz*P#2>&Y~|=(XRfCzy=0 zc>%K-jq}z;JdSYc>CP@0&Pac~PFu8-v{(UFG#&w&@^U(jCgD_;-40r7pC7NaJhFUi zQ6`eDw}{OGHm@zMkyfYxRv=f4-%B`p#w%yyQ}8-0PFJB{X(rwUl0L`jdUhISs8=yU zmd|`KK|un=QDRWo1uEDgyPxuIQ!6NUoL;a5ee5%t>qTha)j;V!a|nNB#TWcf8^zA; zwk}{h07!z2{D%Jz5Q*^EJ%qfSr+5|KIR4%d?NvDBRDG*x?BmM=dDXrc{YEJO7zAMe zz|`4;$bb)%VkJl%$;sL&JY@Pv6u2Ece7OE(b9p)53Lb85be}9QLm@7cHk5%p>%dfb zn-3m#*Oya&P%uvMyzYP6`o?nXZ*6tg{0_eXVZQnB;l?K2^`vY-G-fL+GSrPuGw$56 z*|$N1x2$O8!DFa-5Us4Q_o9`}hg<8L1N?=TCy)5$$)n!56d#(yV@I9!_0FS*-+B>b z_E$V_4cI8??L*ja@0*3K((65})8LaA-JkirXnVUWqE3LX=!SoHd+*yzNa`n@VC+Yf zyr%)>6OilPUZ?AS8{PM!&IJAKzI4WBEt^_0SUtq~$B6O;8IOcH@N?tn^V<{e!tdu> zYv{WqSTo#r2>lGVa$vYa-&wHG-$v}Py!_d-b}5CN#d)vfH5JZ-e0yz>ce=f`{(LLz z8yK4g37lPBz>I(6e*XjqeKp@kNBf_>%2s9~ZxXz9o0$U)`F(G)9gMH9C)=Mq?{p>c z?~l*{1k|DM5bmH(F!^>wwakK(tsoto^-i{fv~xMQ?47KTjBm0v^C{pON4Nr9G3$?@ z($o9lg!I6? zi5{53(k!3{^1z!0BbOfN=M*7>`NAoa1pSjO0vHJ)?>w?{)6_tS9hg_CfqZ#+q^W^X zBQ>C+9L|549Gd7QfTL_ea5vG70+7!L=y**};V^?%cW~IdO~c+3PZte)7ZS%e~p9xqiOIj#PfeegMS%#FM{Wl!N1gle-*rtgU7%Q zTQH1HC*D4-cIg#4qgKt`3u5sX?)|@L?_<(;!C$;N|5BUtFW#K@w!X7A=a0d?mG8u# zutmS?Yv}smeb@Q%pMMIBQYY@g{`&F$pMGh5zQ><%m&W2P0823OX*+Z}v(j3m*Emam zR2P5g^rV!{dr*-O z!byTUE%D+@Djw>J+eqcLJFii2#}z#fu3*h_62Pyoc30QhVm`{(dspL#j2YgDD4~aj zdT+;ACv@|n6tc3HsYy^vAw-{-F>p|-%xg=vxudhG2y;5v`d2{2odhgx?L;U^a5`P%@W-;+c_7E?V!s9TO1@N(*u2}a4G(dlJ zAkM5`bed>uBHB8^hW1_nL}T~K10)%74k-TOO12$rDyp%mu?MQL1#Ng6T_PSguQ!oy zlmucYFjWXB4Bgl)t!_B&KT#pEZfYOS&!*3hZtGt6A=9?&*SJi%>S@^6(q2P^OHypNxz$*kHxAb zIRV1gMN?KbBTB=dM3#H&2>lE}?I-N#TD_PiRmu&Gy3Huro4B{ANbGjtG|ky{Dn6Ko z@$D-|isHOGH;=wBsd;=b&Ewl0#;n$4z%7$l&^&5+-<^B&=RC?TsXO#!`a^%OcU}Y% z8s524Wnn<=su$C=wq3Yu>q_c)a|a@`d46;hZ91gszt+C>R=@S{i}t;48{LkrS<1pc zUG80ND@#}iB}gbRf{nZGro_Eqyc{-avDGKazttKAUs$*M7bl@33UEos*C83qkZ>jFt2|Q z=w-{A4<m-yN?%~CkJOxTkxlRz&l<(aG8xSp2kNEM=|xO$UQw=ICip|IYwWpz#u5jIs1G_{&C{&#yhag&R)VVz0BMG^ zf1xOM=k=MNy^I z*1p}Ad*#08U#*q*Y5VD2^@|}Xt2PcOX49z2*fewx2lflbLCb&8iX#c6C!;uv2h-lX z-_GYJC-G;3sa0*Zf|xB({*e$_^8?I2{2y20{{40*VwjEfKL6R58~6tdASMsv7`I|( zPRjUT1K;WJiVq$fQatReFmy_M@bFM{$!{JVG4a7BZ5()K93LM%!crRX#s`lNMV!A0 z-*{Y?6#iqaSebuM*X*tCD4R07TPt1me;{Q~DApWcS9>}u^|+c1<^l6Pu=0K3XsR_1 zsKQ59g?gaXtpA{_k9F1sbD);zKEXCaq5myFEkgVC$HDc-e_Y@5?>pll$0?H1kVF68 z`%^yRy~4yk64mUgiKQepwNBzGg+8|uu!pFYIis5;)(3x@oq^sUs)<2npfu2CPVJtR zQO%c|H9XGK>AZlfPVzj9D=B$6i&nC6@Bf7_H2j8UH$Y~-7~ z#VxiHScujrOlYExBlMpPCw>u)Q6oc5x6b3Rbv92fi4%vZj7l8X+%Ku;v145@MVNI$wUp&F7N(==8~= zBr}`F5?*tR)b;^DTgS@=?SHO6YsQK!ss}Wo zGcNI0$pZ?&+bTanA)p9p7rG>KB>k3Tb$?MGlIZhUG{Su_258MALUy=2*nU%@4OYGN zu~$r4sfExQk;HG1{uzcm`g@2DcXt52?_htk=oV}iW4s0(k=S`rUdd@U5Dv3;fD|6` zN6QnXgWjle3%wzBlWaBj8gZPI^QpRe2Jb~K-plTU_cDwD#n>nM8oY;6HtJhjb__Nj zbq9BH4IgIZckCW+(ZOYjPc&+hQWIhAZgmnd@^eDdAy!*dyQ%@HBvl;+1Y;or+x>s@ z8%at@N@^8r*F_IX>cwyUVpW~%d^MGp)J^j801!g1s|vW!d5~M2Gm=KYH{bu~`ir)& z`gB+UO^F>ANefhwf7nH|xB%1Y`!I3rWNJHcy>Tb5+dFZcc4C4;YUN!` zf7<|J6iEGFJlyVlq=KULF7zX$ z%ALg|B-5q^{oorC#|6qgm=bK$6fuch$Z73a-cg#!%c4qNa_!i~|5k_i>p=RpDk`8n zs8*wg5V&-KmB`1wmB42$!}~z~$a>}0QS7vQwRPyYhdN!q!_D_pf1EeSBfo!J!{#Ty zY0OUJ!kTO**((Kl>RoLP8$6=gYDCUzNHRib7_+gH=8FpbC=$yWJ#x((a(TUkEX$|U zc8Nw*ioSyZN8T?SS?3pzIUI6Snb@Z5ku3nJI|~{_LB_S9M^-!JcYqowVyfj%qYREr zFOMp;+6~py#%!!!Zev9FmEwQJpy1*~Q*q)KDMLZUBZOwl$USncOYq<@7wV1B67d2Z z_p8z#axNdlJ!>B4UtF7Q@HnrWvwYbn3iRsY{gSpY=X!5xO%OrfYc`dUSi@^Lm-qMI z;nkL$eMp~%=Mivhbn2tOgHmW>q*65_Yrc7e6I|0sIJ7}u_XMFGufl(2g9i^bdXMoi zY|Ar}DQ5j{|couE7mY!LfP@W)_WJU2Cqeug3*x)TFR`>r5oz%tR#GOVYDp_?$u1bhoW{?pAnDZY1$I~Xv;itl>ri=W zL!~&2P^@_w>B~23D^Kj}DSzX=6fueTR*$-pBVf?(Rh~&ix@~{>v7egn^EBsB2|z+t z#>Cfq{z=z+zEyVo|DsVIef)U!@#FQ!k0oEoIgaE-AG=KDN)S#F)w}ia<2Ez{6ZLQx z648dXExv)m?T_%k!*6_X5n1<(8ZQ?~3;z8mu#CwsBeq8$I;k_6y5poOWBK!l4D44` z7Y@IH!6*~^#u9(f%7x0Y7X`bPaqK6Hg|(H+g=Dh#VS^Su)(5<^025$vTBPlp@D1#n z4DeULsA7;wLX7v7Xrq#ez1ucm5+j_7h+7C8L9r zL%+`!O;lMvXL6yJt;)v$&T*_1IYKMraXP-lT=-khB7NNS*wp@jzOUi;Lo07t#w>S^ z!f`}Fq)QhIYvau^4B{+MqK*ETG;h*Y>k?4e_|URb#ud55tDVpi{-PwLA{V`c4)AB{ zNadVn3x|K~@`|zkthhrsfXkj z%}!z~U(xzf&uqRG!p!DeZm!Pq> zA-CO+)J8)Oq_ z-Iit-m!<=Vrh~QIt;`;l(O7q^BjPE-D;UeUSVoyk2IRr#h`d$*>tpY*h;`9}I9VVNmAgzd48J>U8>neH>gW+lK&pbvi!MM~=l~2`%B8P>1 zh6`!YN>`6dR5z~JNe@c@YNK@1y6fe=`{Iqe;=TDi9=GpC{$p0y<tM{;PwjTCIP> zU>b>62P5-7!uM12ev0p7^FGG+cjo;azCShZPx1YYd4Gc*-`LD*FL;G4q9_bDD2 z%KIEY!`~tNXT=bZL={uYFCUOe-T#f^DvW<=~j^QBv;TX;l^2t0$C(Hn!$3QFoe2(UN7s!xYh;cxuG}yM- zJ<>akd3Uu3(+PWo;VP>cJDEPC_6Yj)+D8`Tzzvri;8lH?FoR6e%s!H*NLU)**ke;1J81&Ea^| z%H8NU;tvz{A@8-HM`u|yLI;(tKXL^SdzVQOeqPWldpSq%Xin+I7~l)4FrLPtj(6lM z9%DkPFs#7ap0@5$NVBkLap+&HMFnleV9|e^qvKfivjjEDJG@bHnOZpe(W)w_X6*|K0xJt-HM=VPrft1BAP`P3!ppp+;A#xZKTkeEwTS|;_VYNW z3*uaLYle52Q{WyX{a>BXTQOkoYM-ujrWcPgN)+m33iS4ythiBM4Eqj=^ zC{<0moN!Esp5h#6;_A!FL6@W(>iV>;wo5S!t{Q<7w_Fw0F-=MbU^-`U@`~7(_WkxO z{4Ad_!U=|mBiCOta|_jf;RyGVv&$?A`ni@%aS#BJid=+ZE~a86PQ;n0c_e~L z7!5|f_B5TSoxeXnn_88g=}J#brIf|4z80!9g>wY=j*QUTlA{o7%a)-VtuF zJza1&h^jICtdhIe*Sn%hZK$GqR#ExQF1vSqy{CV0CDUcP6frQuSb>P?RrDzg|4_*A4_P&;MBn&xry9dma+6;lG|b{C_pEeD3!=wR-hLRkR0Y3<+IF4D zQ7YYUiYS9Ulg{3uVyi}p+{DoBadi@tvfj}vRh^`byf()IfTdc{d+C{)9g;?jXKjC% z(YCi&4mNhuZv$dO`hg^(xJ^zRrySeU3rrorUgIzmK^~Wvx_&t}{n9<6 zo+6BiurEM;v4_v zHnxnkuWyV{CewDX3nn<9!brx7+$;bhR(T-RFbne$b{>oS3$=GG6)gA4TDD77>~VMz#ziZ2L%B&;?)@*Fs@!&u?w6Go$sZ~}`BDu~mY2C3cAtN*?omjX z5^d9}HRa?B3U6pw5ME!R$T#sN>S2mwwH;K{xx$3%HQm6#ebl$Po#@6H!vHN#CXnlfk%#90(Z%zX3UER`&!fZohA|$MDY_)Edbsi^*q9d-wgu%3Qi&o(&*P)ol+8_0 zsVv|TP2I>+b}z24>u`~2xDbDCR)w|Xa%LRZq0;`;4r=948Bj+hs+F~})D5qiKgh^& zh4S|yQE4?-S(XmSA_r>GBGn+z3;n>!UX#ytzcScDD2oTYWMqLOIV_L+4UrRCksIis zinS>OE23g!a2hvUO^NG}k}EI)m>>e>IFeGGBXa=)35j_n^uqOZtWJM#imUyBBq|tY zqY}ZR0TW~t_Y)0BY1oxRnnJuUo^yNux@)zxMh4ngrCaC@QBarG`uem&mR`cGb&IcI zJ{#_z$Z~ovLphslUqPngjc2P&cFt=&3+>U$$TdiXdF`3yTAl97orf`tG~IBJ6y#`W zO`n8zOvs2Mc_W?!LbiV}{_Uj*7ZHba<%KGHtJ;0?Bt)Q!Z1hsFc)_Yuq|k;FhsOk! zN=h5c6A4i)h$K@4`wlwt`#!K44*g!#_Dv-w2=*&C;W)IDeY83lKQlnwi-@+dng z3+*s&BK3t0UN%nPds1RTVFIPagvAdMkpiiYyCB70Y^MXeJ%HM%cJt z;i>4*NtSEJ$b|YL8!>&6OlhSN4jYsqGH!@yq39oqc3DTNS##gAhQ4Jo@}#2hdo@gi z0%#kSdTJ}9*+hQ`=p)L|x2etPT)IJ|D#w@NdAxO7<|w%q8AxWTTdSAG;oHyscv+>zZ?`HwvAjSlL(2 z36~Z?QSOp*_*rkjs<@|B5bhC-Tn;*=Wo1u@wYDj;(&v9lv?YUjC}4R6Ac?vSj9=nK z!S+)ZP0B6y#vxht0fB61!9h3BI1PzzjMBlPTG&PS#h1u&e_<~3-B%Z@YF(osK~$f* z1zYVa5J){plbK+lccHiklU~h+mN;@;cz$Srtk91n7QxV)NI)*a9s{ZFB}Hj(X{nGX zxmxKJ)uw+4vA)`(S~g+h6xF8LTp2}ZTg^x`qkEZg!YVXBCWAp5tO010NWuBJ9ju{& z4(FB5CkxRv6r0?bEYY~}UJmU($8=cEqY~uM5ymrXo&8dt$0_0}k8p1kY1S)(wrI5} zVCc_b*2{u6sdq~fIhs2yeEUx=JNcMFNIk*;&cJ`Otf~VKRlX&1F-qE89{IlZ0z=n% zg6*hNbTZ%Xwcn&HNXy$L$z5Esvckt}VCY8y!mczxqepF>fE0Z-ic(?LE3v{S>Ch!I za$IDUi@01I#4Z%z$qr8rvV!)hAXGl)S>Blni^R8fP|eiK=dUSEG}F)|t+YXTcpG1X{qs-}gMu_ZYSl~hxP zpUQ*|1lJptE_Ihfx2G!R<Lrg6pmBw@L!uWocyuECB` zexWyXTlUhzIkAIt0E_ig3NGZtY&}R0JvtzI%D&^?Ra~y(>2Q!9!ogs*wr@LuYuFP} zMNUzL2UF9~GkkHCrYAHK`AuS=s(gP!-jA@UYZ`Jj9}02o7^gd)Jx_FAm|n;ux?vry z)4N|7ErCT4Sd+E8D5ilb=5Pp%9qSakqI=Zhgn4Vm<|#JWPIfYql~@iA#KlEF`{PGq?G*%b93hFk-?V^OqT5fw70eOzrxY|v_`nhmAH&3Prgvx!9eE%j21 z(g#A8BNj#_QnRQ5Tv`cEgC$tqxgzYs1JDPSpx{M|I8o-p)he}i&cHPxq)TzUW#T00nn@H z0D0U>WDb#81Z|zkf=VKb$-?PRfXNy}E{~OnHFRCzMRxZK$GU)#;Sqjs;aR0_N9Y|@ zjoATkK`Plj9l|*38^M1BU2&G1#~^o^0F2uQ;@7ICE3O_CCF8yfH`;m|u$Jua4*Y2u z@O?06@0AR_8Hu;3Tk&3=vyJ;1Ma{gVzZ3ksz}$VZ_-X-^Bk;ob$nXdt`Ll`=FD>?Y zz_Sasus**Crhv{b*u47UBKYB4>|db8_3#2MtamQV7HQ)YwQYZ}*Re#|-H}4XlPIyH z_r@5zH!y*HRUl)un@xosj=qcS@8MJDG!qWQMfLX3PVcr-aS?&{6A!kr!YL zGW$ebxL7XfI1CSU3I z6qq;#^wj{)U-}jhS@fD_4eTDpxSLYiO#n#Ja5=X&RLDCBwoXcyY>~2jhUn{aF}ToB zMbw|1MKgZ^Bb)h=U5`pB&N}MHt58=wNj$3_X*;dP3R>{*Vy5DS0CmjL+j=pCgR>u1h}QQ!F~7+!x=;Fi<9SjfCWRV_IWwQMnT61ZUc z))v+xx)lKpdwWxbY6R;c-yo$KSd7;MY6GLo1NOiu8x4$}8d{@t8W=qZRdw^g=v(u^ z=o1a>wx$Zzh#6R!4BR7QDO9MjE@B{y3@HlHzU%0MjP<2$j+GeTve4KLHc|mRqv!d^ zjSznh^=Le7Dst}%u;)1+#j}ML*hD(L!eJf&{#GFN{>R2e;v@X;?T z6w2;}O}^~Wo8mclE;uOa4P?=$8_1$hP%nSVzEIGEhl)!Ly(3!ZvrX&FWJZ_XQSsIl zz4P=!+tV$edL$qE?qZd1(a>O}Ko%(H%y-dGTs<25&cWEwy+4Yv8Wavy#BzaR=WK(H zUO|uW>OI#`l+rHd5yuzB})fy#dvs4^; z^FoNh)L8O6 zBy^@p=r;}tohcF;EpM90=6kVaOzBfhhFo!@`8Vu?&mk0F3)eh&;RNoxL;g<%A_<`eXdNv1a{s zUahDQKVG;hU**^B)rDp#*U2Hi^1JdUOeeZMT3)vAhbWrtFLZ(sjii6(O-t97x|;Io z6zJqA!QXZCh26c=&`PuRgiH&Q^ep zr{tA9pbwk4kK)p!FtOLy#qx5uvG-O;n+v=D_r9+G+A@4Q=u#)U>(EJh@u08YT>##_ zzQ&0J+Iam*Kz65I_RoLr8uWKItlwXdP?HY)cWBU)2X@kHHZyS2+%x!RK79?S{Qwk)a~wvcF}U#fG>g

w9#@Mm8`P;@!t37jC2+Z2w0Ah<45@TFTzIO*XD8o?)j z^Q#r!S}+id(pKnJ8nv`4xS0=XehxUSPCVw$@X6cq{s}nNq~@585KWID4kaa-;Q%ni zw+3pZ5i@Yy3eR6|63=;>wKu~{sB9Q^L7y!Eq4kk@r zEwgnxh*_a{NPIj)F!@%0Z4Tk*d6iIqSTX*&W(?aVwNQ87&6MZ{Kr#jx%_%%nJf%lv za##PffGZrQlbW933_LN_(1UOl$F;AkxRR86XWY#2I$bb!yW3;`Nq4No8|SBMmS*a@ zvyLvRi8wi2b9xvtKoxC~y1A#mLlk1V`z&&jffXVO1oGY5ZlGpIvTT8bKHvy{H76C< z!ap*J%Oo{fX9KXY=X5DXp>!fMPf?3z**UOUUpw0kR{9{$dMHoq=#d=+Jr0Or-rV~V z=JPvDBY!RO(^!1_>|imb>8dOtuv@^Bw9pSSG5wR#(dEVZkDQJSEklEDMA^OGjfzm; zmf3v)Gtm`O7Q*E>u(*C%js?qq)gJj`UcTnWI#R|rQ4vQsMrwjYO`#WEkO>C4FU49Xh)P8I(Ak;AXlMQblcdlQ^Fzu0AWsr~_Qk1SUgjjR!TDcOB79N-#oQ+%a74^UQI75;J{@pgBP7aon z>p^Ydp4j9hj^i%+wj=p>_)s+6RIbL(9lVc&vk=e>lOuy?Vh{?q?A89x88KElzy+k& z9x$N_ZsN-gq};CkyyFDFOl6az$GGTbaq&A881k~%00~|zQ-KtJ5cDI~JbBCqhkaQg zRDBIk$VcR4Nqon#?H+{LDl*A-3O9+Ct4r~zS@8Xet^QPm(YAI`c!`{w5tO2KgWIZ_yyzJ0@L;IxVG@gMp%PykNa9A9le3(-ZSJ^E*!g)622wO#Rp781% zyb9TGAxz#4!;p)ARksBr5+Dd8=~q8$(fA@`tej^OXA}SRC0A-A5~lS-q7o=w=to%z zG+e+~@Gn4T)9)sVHUO;PGfpxg$BXZ6fE1J_F6;jCg@oS*i06nhpd`9s)oMMps+73h z004%`U)Ff7UMD+Yjm&Bw*|j(5UMS6Ga#|7-V0|tjNc#4FqDXROk{z)+D-LZ84Xh1% zUx0N^j?n6TvhL(Z)_f&LX7xGQn`9S~?~-$nV`m;jreC(37`!#WWM31d$Q_4~VmV4{ z1K?*qqnDLiOKR;B3N>VBSbwaSr34JaVje)dp52RPo9v8xZD4p?#E0b0l4lEl3DnnU zrOV>@p9{c$A29SpK>@$2#ZDY^bsIk8aDmobiPQe|ppWgC0Z!VV5 zsV{|D7y(qWn`d+K%a|D0N2elQBUy1~gC)Z0!KK1{+<%Nr!+KS!n^0qa=|hU9Fb-$!9-`bW{#%U!0`_;9 z;>{g6Gp662H^x9YV5G$soKhVz9V2_xo-c&ACLCS_S*Y5QguWa^5A|1T2)zPw01p+Z z8GL~EBh;I*6OqKOHGZ@oj+m)yVZ@ENGydB2BAu1WCe>MTkvtVjXkpQo|l^7ykD2fB|cmXuDi>JUD3{X88 zONOX?qm~RdXn=5b&j|?i6=%e903~xaPTdPmNz9(GqrkaANIP$dHwQ_GRuF#D2yd@f@H2W*KBxZ+y;fQoLndiyPuXaE`#~z%s7#+gfD_GCA zd93S(&3xWawQ)7xg|tamr@o{%n!-t{nQs8Jj=5Xmye9Y??B`yjU+b>mZHFi~Q-Z!Q zh>ys0-t>R|9|E?2 z@ODr*qp$n_!M?J&=I4K!j#u^$c88Dur49!KEPb+DJ||kf=;+Ub{7e69lJ?fk9D`^d zIzc)g7$Ong&ja|Mv+bvSBd|7c;c)?lPx%1%Id6SU)Ifl-wN-k`rN@elZWA?)DyJ!E zeJwth%EcJV!u=6-Z1in@vP9canBi*snSpj+uL;Fu`CfC;J)cojIEsv8-H!=@pa`_z0m zAFO8eC~pC=8DqTkCTlI|6k#2=z~`PKkQglYngm!tkUe9b*19Rtxu)(CCm!# zdnEKK;HNjMl1gzK(C*m;-85!@KOem(tpdf<9ZTR47m4q}Hd-Xp18~s{)Um$QpG)aA z{icfsHJt-GZl~ZaS)rclxs;~|J=USou(AQeX#~^1*t6@kX$mzD{82fGCu%LdA23Ps zH=N=*oGCuJJu{7)s<=dx4SWl4kCECGFP=&YR^EHvy}Luf7fCA%h064Q8Ohp_C_=zY zJm}Ok?4lg?dskwIqdV4ZF?9Q5nJp$AvhV111cPD#L{~oE3hf^SzcOcQM?l@eA$vXQ zLUU}PO+$Pimq1}MhBmU{rV214XS~&nH?YfTqah`2iCAIh~5=Yw6p7f;l%_ zL_+E-LkaR;$H5AMz_P-BquzQAj~f223&5%79xcPQh8t?05SZRObC+S?NXy)&U}!1X zt2BkrWQUb_jEF$R!uzc8r5IZ(XZTMay&9K%0iN|k@=fgBpzcoqn)Q~iGB}p#@8Boy z!>`}Dbm%W-5iL{Ba<|(Bcy4$F>{s3Zjic!VO-q-Dso=P=Jk-cq)p%w1qSHN|n~a2DrR4+;Qea$%Df}L#eCWM6arRiAPEzoTn9A=t z;E~K;Zg15F3Zj=eqcVBOEoDwU)B4XJ$kFZ6A_!e56uhl6Wa1lA`(j8jYVks8`+};m zd*GM4O|KtER<5mocbtCgKfffPo5dxg0t$ZKU?BoD&Gxtm=gdjbdbs8Z(!ZF4U!mdV z2e<@IvDSo|A*6AxW;IwHD-d+8r=h-LQFVx;*Q=XWf8A^DnSQZ)iW)2 zQ@Wi;zzX6By+aCCkzqE@Amao>7$gT`hV+bo60j|su&H@}C*B?2{TPQaupWm*@1B{6 z4rX#IvmP}kpTIg)`|{3uOy=AU#V^d*`tExLxM4}nXE>Alm*e?bNtdvlbC|Y^afd@{ zT=_g?J#f=tLi~nf?sD(`veQye-ZvYn_fRVPkxDcifUHUmf7_&#Yl;Iy8Ih$GNa52l zX!wl()*Nkr7CLwkJ5cz|XF72jHG6+~NO^POTBkZ)xqe~>X&iGGE_&!h?vFoe^O%UA zbYXBSr~aTFklKeKJP=t)(KGjX2^9pSvIq!c5K}Zly4x3awIO_6mG~<6idcwr&0OQ* zGr*x~0Zl;;_cNE!4DIt2fz^ zB6VwKq*}85XcIqYRV$_%<20(zWPEmV5s*+gvKPhi5IIN{5W4!uCalQN3OdJ-U)^$QFyPVjvx!&t@Ja&N$=meSs~2YQLJ_qT-D|+-tUG1drKePUr@WqJ4rXb3 zc$_NMD`%$aGhGZW@8SU(YY)Lcb)aFI6oMpUK?VSGchX_!n9!7OQMz!j3K&ayxUFkb zJ};J$@jd7$xs82kz_6io$#$!-UYZJ`(eXxqDCXfXRi6FWofqj&jG)i6lXtsd9*JE& zV@6jJCS+brHJX8O?Opwb(sgj_bw zSu6)OpD<;i^lA;bC!Ks-7Xx$uh~(Lx;ZgtciUSMSJbS01fR1H>Jj7`cWnTsMIyNPL z|MZiYJ?kO4&s{vV=lGe3X6K z>!(>4%nAAgxizbt>i|VSy1!d_6!k^V-O*M{mRuhBgT#{YZz5I$VwAjET77dY@V&oP zknWuT+C}d^x(%%<3|X!xtPkjTV+bWof3q}T_rSZE=s=LMG%GhG-g-;5TVNV0yDyYP zKbW~0$OU!WBdyQ;4LB7*0M%(HiQY1XY|XlSoi|+5|P=R`ZQJ zqU)GlhKa;<^M$@v>nl?euyT`($NI|NqlvrnIMOZxLGZE!dj>xZ+$i7#sSEmYe*ybW zTl69qeO(D#j9<^}95>ZGDznPb<(N1in(ceHW1x25h>U98Imo8~yc@Vo6)L>%8r>_z zHQeDJ3sQ`FRWr7MkjK1?UUvM&hlFgOpyYC|tlck9qt#t>5kEX;^p~;Dk%%=>b-Ur8^+qcW4Mcf8(-Jd^J0N z=T%xD*+;p$B(;@WPjpLQ@*Xk@>4VB#+3pvp-eYeJgW^@Kih3&xHODoe9r*f90&EM5#A*I1O@qAv5hwc2L?W7)&Lx(NxY%PWJx+ z*qG07LT(jx4%j`>C=sW4hQ_NMYZF=9;uZwqYK{x=aZvRW3g;R7edyP@8$ITzYdq$x zqPjLmpCY}M7yyDoe?cx}_+h3}a7`~4(RDyY(EwNnE|rj)Iut&Jp3zg|fzuylInJ1v zphZyQIbjd~WAkRsFs}a7Xh2(aK2-ynId2V8Qih$(0b8h@F%r@{yCVKBhJpx7!bmSp zj5ADFjzXbHF}snDg)ZGd9TDG7|IJMVmOek>9lr&aGJ}#%e^h8rXOGrD2kwQ&rHRCk za8?tYTv(j-j{2w%c=2*9vJLndJ$UAW-f)a6@K_8?#t5g0BH{jC3?nH+*Oo*7vg^FI z%vv2W*2TcLlx$8%rs_4H53crFTH_>;_P2gv)tW!l>q792 zd9VxfV0cAs676okw)?d}!Vo$a0~T38(|VS-9dVHAf0y+%Z-A#{TK}dcYdSf#)>g{; z;$GnX>5CiF2?Cgh(+7C~*ET8^*kG>sfOnSo!|+Kgp(7+KZeJO3V#HU)>Lo=)fAN{F zA#JR4E0+eR*BlEaJpdpDo~u=!;%-*t05Na&*Kifqdm|s%-=ve@lrFwG%Ja;i9>=}F z^c8(0e{5%$zwws(T=^4QV@RxC;d79$MxIuu#y~CLhUnDT9hwgl#l6uZPOCnz-y%QV z&$pzwbgslQ$%Ob32@a_3_o~d`>J>Ryd?!25uJyF% z za>eXUp{Q+VTviAAZc|ps2(i%k^3wLrrf;rwtcz9u@|^@BU3nM43wB>ttcp5uLo|e= z#S#OYE+~ktznB$K?S~#E#zHORWhj%1;siAFiYl;-Tv4=06|Yk%vy41aQ(lB%t4GMk zf6+IF949&~9SSwwt1E9${I)k_t4+2w0WSvhc*AA@hiIUPJiI!nrngU2V@{o!Fgc;^ zJcZ1Mivt{vi;v8)D_0Xov|Xf+{J934?nQ^`Om;)+%G1q0)IX=b^5pCpf#u)&QPIaYOW6$)r<&e&? zUsMIu^<1>-?1-i-h+Jsqx&*nZY&gx>;UX^9TI&L0<9W{tdL`rLX0rFZ^jXdqoY!I%loaUz&*gYRWP zxWyi0_@)c5BzCS_CQIy02`?(KPL?ya)qu%akzKGYRRr+@_5i#|B^mIW5^*lgK} zxQ59;LDmI1=^0H!@)%}Z!y|_qe_?yAWa*-$Tt$oTlg5D_`gk@mb?`EqQd zcO%an8eR1uk4Gzgonn+&#A?mOu9jzc%)2`y<7Lej=jdi7Dz8`3wYeiegR+u4Qo3&J z&c!E;#p%oitQYPSP749peX_sj^{|}ag|PoVKgGMD9r7)v&WVsH zrpkOVg>++5O*$}Ch9*4=N9deAOUE&+u&2VHqFO`}0w;Y` z4}iDgpB~#{J{`+pR5$*Le{1V?#w^@xjY~IFu;9P(Iy*oQW&57BNo=y4jr*}c70xJQ!X<>5y<>`D%ak6x0z@hwSHNfo*sg{vG)H-Z$IN+AK5+m;F7LiH z_Yj*6!*X#h$m(;B5=C?o73?Bjr(B7yIPad#0+HvX4}ZCknOMW@e-*iH;;ITvqP!!( zvDzr+F~*oT$a+@B^>YU(Se#0&i;r@jRsqS-)1yQfSq`sx8e~1wTZ&}#C5+%M$|>G) zqdc+@HCp10MXv93Vm?|W1l>RrvOH5H(Py1~P{8d}5j*Tl-VW$@Be>^uT3rfl;-6{! zS;MPe=BCJhwFMTvf0*bmUmM?sP|81A#xTKK>l@TMKzzmiXWL**`j0f9vBKy7sHK{P3~}F}`fb*G02ctIUSLHNO+VnXwY1%Ts_~9|Oif!jG;e z|0n&&6dL0rGd6UuWXp)`&y{ge74!I=M&Mm01quJ z)Hg9QYnM?6!bkK4h}SclJWR)V;=}hJ%pj90-bF$!e-v2pJcImZ_=EMKdep6ea(2-`@1o;tyT^dL) z^WS%2fJo{?*Y3dpcpCihPdX5w10Es-n|$R4e?f-()PPQ@iqif-(ovq6?)MibagLQN zh+!$Z8|P56bQTBkN14)`zU;j?ATN|~q09t*NJ9<^Quy1fGGveciIB`OE>!^WF^@<2 zP0rY=EwSe|XB6SBU(evx?8kjcfN+0i=GSYOciA}{GRE-Dj!Z~~t)#p~WJ5ZR#ZhU> zfAP#ObL0y(zu&UhiBX#?kG;TZYcKxkyg&pZTw^!-`h_F8%?tDW2EZo8%jYvZKVMWN zHmiZclmKV--FivvxM7A(pCzz>qPcv_;d zq_u0F*OH-v>>zMO3K_qON^JEKSv-A0{&j;na2i_W3OCg;Wy{C`#bo$i9&$*ge|JmSounvIMqoa`&1Z)|!e#~7Tu2rrzj{l7KHCEb5w46&RT>4> zi4Q3OCkoK7rG>aZGJ)uT`gbr3^6-nag{pnX4A-k}(|)?Bdm;D$zpb0B_S)21Ve@i- zITD0+GkGaY-kP6#kB*_MFSnafe?7|f6H249#Rd$?2otCmY*Vlvr&xbhcMe#_kMT_G z)w4Qq=tPY*pV?={f8Z;)zm%t|S)FMjVw<<}bTg|XSq9I_eh(ems9~ShXLDL{PdeRO zU{Gx*aeKY1#R3s(y`vtXk9%pC4fEbZN>qVI^LWNs%a3Qdk>oPrTdegcfA>^3J4;d% zhG#HIRx7Loe&G=`8xqJP&Rb!pJ24t#^fu&@&dQ!APC_QXOZ+>$oPNo0e5d)@OiW^B z1}b*{dPj zBHrd~Wy7d9Ef%!a~jUahjw~U{Cu3P|sL(>xhJj zpU_%RV83x6I*qjee||?WroBi!(R0sqG9@I$lk^<(FFhfTO!L?=|kk-Xn0eWJei&Kd7o zPgfhnl!T<(%*krbX(2l6d19H_Bf+1mr$ixGa+*fGaqO4vuQiBLHJIzCsPV4j-Cef* zm#ba&85eTVFR&SE>pt0%+*(-^K-VQ_O_M1Td2{s`H9|*Dn^vy9Hn(YbGT|Ze;;YrJRy@{|FSTr$#qu3-I=qN*mh6|?%ceaQC2AK7B%^KQr@-LS*sN+ zxZlka=6=O{@D@I~&qp(n^SZ%=rwx3bCs~r>zVj{#%JvuCNR-d2^*~7G zPa;>?>#7LHn9ug~%h)*avKh>`rFx`QHl->ImaFfpR|8 zDmJ#-nZZsUWZF11+JBJ7%ugjhjhGw1@ zK#$#v>6C$qf@rQTUMJN)%gfgZZIK7?Z9pnLOc|xS6khagXRRF~YQz~_Cu&cuDhNbN zpS8$n$I-tG*)+H!VN<_m&7U|aQ~RZw!0Zb1UK9l7q$t@bUfdlJxH-#G+ADuU>4fF{ ze>5Lo=cxP#Q~r{-H2fMXbiAR?&VQ13y`d`pC2rCT{c?<#cat>7tbf@xjhd+^cQl!L zxEMI{>+kT7>Zk@f!8BakAFqZ(oO<`UT|ue;Ryd z|C%(`ONokge?h(A`|!TMI9Yz8AAk2`v2R$}HP!shgVUL-l=_i-_KIrJO!PSBM(%)p?cQsVnU9K>t8(Lgsajl#+&fj`-w|xESod zX~KEY@OUC(G{Jg=Ji2Y(Au53aA)|GT9c??o(~%wJ&r`*EWX>v`n<7_fKdV>ZVINNbPNgd zFkLEEHiVUqn7J*xfVp@!ZHwAL6!Dk4{Erk6Yxidb#5!^4+w6|@&S}J*f-29G=L^q2 z%JWNGLzA+jM>>W%_Ls!Rve~z=fLH54xh+;($Dr{ z0z|L-lAhTOA6JU^QYNf1eWCWMCQ3G6(}}J)17#iz7IpSF+3DfJt|GlsZ2AhjTk<%S zOUw5F&>ks1HC>E=|sFLM_;lP*L4f14fler5hbzj{u3qx$fD@SVjrB*3OK@Qn5v0KfdxVP?0cI_*@p zY;@}k6@Wx=^-LGPyL#9~!N0tK=8ON>1$5lw0?O=vynx`f3Cq!mjV??5{S`Dl@)fi= z{u{5LWhEV@j7O3Ssyb0OD^khXZsYh?MxGgj94MIJw}ry?9W8pp4W@7=Sj!gNNzLl z?_Xr=4B|I38HIfB99|fhyMy`@3XKEx6h3}%?*8&+e{67)^LoR0_}BXAZIA9p(9M6B*` zc0bddYr2z&D+p(Pytu|KjQ=6GFwDo?!YcodxrKZ_<`xD8<`!nnEqq58u7qnv=_PvB z|NG}ze*=1xO$%uSOM#@!VN1ZUB-tKIi9`)!c|1v$p2}lN1<{k3)bPB_PxgYiE@73(Sjfcjl6_h=RCU6%4qkj*22A%7@E|4=FK z{JT;OiRh+MfmO=40#l___M1{BHU{og#lKN1e_4Qabq!#4{I*onNl_#aZ5j@Ezgx?? z9ZvkWO%Hz^PqOrK0P4^b!LbC0RPvlB<>*i^T^U2&i1q@*-3IibYsm`F(;`^ zDz35c=+ArwITLeBVBj*KP#!;;o025=3R`>MN@sWB-{|wb*^o@1obHJ=t@@q9?|EdU zf2apuD9K6bRW68!ww7+4O4h@(+5d&;q4z#5$itj6-RitgbLeZK5Vh0{$0|inl9-e{ z4t|~Sqq%r9&%9sDH<&H}l)(;juT}Y&U_MO1;8<;?pP7>VG%FoF#bv#*I!jqX*O9>T zc6c?)Q^G)wyGk&*T(%fQjKoq29#6AWe~fAf*}1Yjt%QGL+P_y-c|OY9d0ob)=7PNq zjxxGk!S3;1o>mflt4a;IytTnvM@GisQHSk*h(GA_R-H}vkdjzta|2$aa*F!q4OLZk z`KAz!&!4KT^dgmyo<4_6th7d&!JbJJySZVjI5niFx+u%Av5Txw1iI9`*}i+;f4(TO zxG@>+s1C$AHq#R?YA(D;AGfRI^Nl>;Up(J&IzjJozn8_}xE*%xq{WDiwf%G|PiH6Y z6+I0J@Z6N$2a#qxIH9j;^1uy-y10>64njLP0JRy7xTr42LnT{b|HdY1_`%*RQ+Zm5 zpEie4g7FGCR(PeKf~b}9msTpQf8%|u;`TfpB4Xivo~5!#GPAdjN>-k3<|;0_or40DVzT1Dmu1tHcG1J&y)2})U@|3X=VhvZ zg4#kZVU7XY2JzL!5M&y0`PAKqA3|R=dGR~VF~ZiHj-?<+wmYXAnSchcf7(^X#OqH_ zNDjX^>F$0Km*~)&CwXy30tI<7|2r>!g`Esv^pY=h&HhcjN^!6B>v59o?O-A~0ocXV z#9;)Dk_W}bJ`i9q)>H|C5+X(DIfCkK?4miO)q3a0cqwNtyWQ#Q0ByqOFzKFz0x)Z)-`q(=8MTDos5!YMBV;s82 zMeN;AgrK6XmY-}HOunf13p-xId4VS8OZkNgSB4fBv1o@idvEx>k(t(qEAm zKIm|^$YNurs0$$r1x!`qYf1QU0n7ao6K!TBTI*emv)pu|$o8x|nEA=tS;D2nFUTiT zU>a9~Hy667^FR{FO!Zg#2k@@X9degMa6`c-^0qJQ5jsLpU>SE-BV?;_%_-Xy&*^~F z>DPp`3ml0DfBWX4ZAUi`Awih?rfL@!3PUkhMpk$#%N83f@sJ7Wlk_f9aq^rPQ#^`> z7x!>!hYdMhqoj(y;w(@2 z1&tecx?Kusm#5aK`egSvU4yOSJYX^9SXT5U6Fr;uEjS&JMg_*e{; zaks{op|G)BCh%F`kh0*6zPXmf!$kGm-uiyOs0V@Sm%12oA`-lG&Seef*`CjZ|QjS zs5%jRB?Q;BmTVUCvMQ6RM?6ztD994ZtIJ@^f3Y5|`LhS%oy_~f5b!+H6ce7;MS+T) zCh7$V`y5)btxSr9^<+;R&$tHXHYg{$(WSRU{SNR#=^ryOmiAHT8j4)!@4}jxbQh6% zaX!AruL(9xrC5uiyu;(elz6H#^C-xb(}tG4D3-NN0?THrzA&l`sJ6_-8b_kt2)!Rp ze-pg~1p8d(8D9D`0X}?VM}(})Jx7AH=iw@5!1@I4!O>{xh5a<#S0#?bWj5+PcW)yX zH`rvDDl&ugHf5ZK?w3Av?h*!Co85aD((JU23Xtarc7e$8NHStC&zOJ(@UNRYj;C9? z`Ep`n9mRkNG5dj{#W2M0t!|SyON19LGr5+?GK+1_~&|LyCMi&YE;ym z(}^-M3gPfhiRu_k+j&it3@>y<+?bGUM9q!9E@aq`r>=DrxKreS*c`+xtgvLELl6vSmel03T!w*hKfpvvZNms z8LHAO+02Gll=%iK;f*yEKW1z*aYab>e_m#kueD0$6EhK9D<;rWtlQRqfB1nxBU}FC z4;XOmmt!45-Z7sRck!EpoYfHuNanV#{AxcKLO|Xun^s64tSmt#Iz=C@v*!PNb7ysn^?gG z3G(NMydqiU^D~gX-0TbKBj;)c)nkfe)Ktkmvf?5Fe7NJV_11b-PayaVCqSlRUhZfD zvaav7S(LsUJ3tTFFx56&z^LSgK=U&$+9GE-6Z9C}S_+%Fq(I0zeA!#VYDxEoPo_;NigMYgDyoXIaO6Yz&AB*EW>((`4j{3}c z1*2sU9kqaB*KO%Ce?chyysln=%$gOPjCpEasx$pZOIC!(y4hT^WXCVbL$C?Ghw1;O zg_3OGnv%e1H%U5&OP7swqoup#nI=*)U4jBkmLUbO_4;j&=GAmvT%`cQE-X}(N?r%M zIdJH6kkBt^f%nVAQ*+B9r)|wB$9yIa0nT%qL5y#L|M>&4f2{rc_PqvnsxKNB*LzGX zp;@?#$!@0mbm2~L$$z3JjG()ll2T1t%v z!Idpt{lBuMe?yLK$`Ku|**@5f^R3IyRg0}Vk9O~R>n^B))i#vQ{|ZHh5XcLG^lriB z=m4^5ZONHptBC$_7j%EW3;ZXz=9xu6+8SHFZ*wqMVx@w_YXk7lNZJ>Q0C8n&x-5Hkj!(e^{GJElxrDYrnFEgSQdqaCJT` zuoSkUi&D_|aqno#mj|HTXb~`yp$aDsRfyx`7!N#(7_h_So+CAmgd}uqQC{4jf#fV& zUwhCDHrRHSX~n+Sn>49%nzWy_)1%k7P89GM$KLp3<^GM(7yY}?7yVD1g$J5x^l6}f zhx($?Nf+NnMwZez){k!t9Hv)9WX$a5 zo5&a`PRMP?ZDQ{oNqw9xA~2><{Nuowz~vUJf3vS)VXw*XzG<1m7$)Vgjp_wTAzc`G zp8QLwMi?VQ0*m=S@y`Pn1E=}-i05zO2A>^D@A7wvXR(5i!9i91hl%IB z8vFJis{h!xzgmrb`zI;(?Jpd{vFw<5KA#iBbE`L{`c7C1LZ))dqrit)|->;Iae+_JA;kTq9UD2nN8Y<&2XWBmf5|jt zQR1u~K{jKXK*M{4H&r>(n^t4{#dBqa^s#K49FDC5y0P2V|DC+@ZweY)$N29SG)5g$ zJ_X<|b#t}0ROEwcj5t4+i%l_qP_FF+ONPk*$Hqo~D{;Qq8o{Fx6=Gjbc4Pj=mlG~) z#-UThtAQ$UehMHD^BkP~wJN}if8s6NZfpOB6C`-kA6#Bp*7V^woP{mAYYdRaXX8*L zjwfIku$pu6mO|#e+XM9AeMm>nOL3O8tpmMr05D=wvlePaB_1Ci|5_<$S%b?*5iTF4 zh6PHF;3g!%J1$7P@WfCsnm2wkrt9t;`XOx~Oss|QK9TH{9OKwfjigWbfB#$Mszbns zaRm@0j4w zW;bYbQPy9Hpf=8~e}~-pgtE*2|8QSG>eOLUXD&`=X*GeXVs_j>NIP`o{pB1w@)go9 zyj%`s1Q#e?S&!R!;c(4YfA>pqN<>{w=7n-d{kCe+_To?w)-abp+;X zwk8}8_3Kl@VHv?^?@&MS413Vq_URBlI?h!#R}Shh;?KWL67d}vm(=iDo&DfI{daw( zw{?4GO?l7iPqSyu?t;hR#payJ=1i}?I?dKftH|a4+4$OpGV3!jPARRYX}7H6WGb8# zN3T`{Y(I=9*GlPhV&WyuwH1gOs%R6rD z1~ID8xsi(e$uVf@aI*?Fx7>~GE!>kf%JC(MI+s}p)4ePrf9Y~*-$4C)KAs)C4;Sni ziFV)$jM5?L;Uw7iq&4m5Rh+_Y@eEs}7oKl*hRVxHEg85VC@(pYg8T?P`^;Zht=HTVH_KKcc*;L5}l6 z_H%p(OSisse?l_AF~Xvsz4;3rLVCR|6qnmO%<9&+`WDi=rQi`t`j8Ubo7*S8Pnn$1 zkj|15s(hqDAV3)t&d~&|e?9B9Mn<5)q9G~BJ)_SI`Jo2FJx-jM>!n!0#)aaW^{Oml z_pJelXn86X2zFr}*2FOxq@3 zOz=;CGbCQkv?4?#`Y#9VoRKk}u&HPSL7qhrF&2dPKP7n^s=|tiV1>!M^PCSSlnz&E z>au4n)&esbike}`w`!$^`-s!o`oaMY#EUr3!Cm3*GFu#q?Y0n8e}ccgst~(`e!XP6+-~kx3;N0hB+6)7vCkrVLMXNcDBSV3O13t_n zuVZ3ZDIi>L(Yxkxr!H$T;TpG5RX6JjIo|2|T*gKne|Dn(B4dXPyh+oS*EIZ=<3p9+ z7XZ>IowP|%j>Lu5?^cw(*yD?z5+&y_v)I<#QOb9(eyT`R!%K!cO2Jw~1Sxi0^^ zy5h#*&sF}hMUG(nNA38M3cLDm=uId%>>;I5DGBo0sb3?Om>hzmqeU(Nz<)RrfBUK{ zeFc@+e5kKX0F;L5J|{TQq1m1`V36zR;jj0W_#w01YYt$EQ@(CP|6o z?>X|&pW=GjpeO!`RabsUkQH>!>K zPnhzXJ3|V{+m6g{d_&co>Re*>!gd~|t~W`{K#!d0K^u9UoH&+EVkCJ6^j5Vat2Rf^ zAa#=Sl$?l=Z>FvQYW(|tdufHa2so+2m3i_>TOy5xMQ$#OFrW|gF3m`rbkx_1e=*EM zgWH>`1MT$%rGgh3wdx{tQOiI$D_E12ERjz(si1Vjq)MZ0$kJ6uPpcKFt;U zL_DW4QK-E2ev(FV2OeZMJFJs?M0X+pWX3xq8 z{H*2w&z!E8?a2Pue84?UJ1sP5rJC$CgN(nr7FdaUM|9a{Y7IWRqD4$&eCH3$(FZT` zAO&}#bP4B;CMT;F5SrVo1wurIN62IXr*l6GAa{pE@TtfNCZE|jf1{BxfkfXeFL#eM zMfxF)Ku1nB$u3auu;YU=wx+Wn?v(c=kAvZXh5F9mfCD&si~u##YW!%P(VWG<`i}o8 zzba3h(Z2eW_?k|pT^s?~Wj9$N-Q!C&FB_;AK16~Lw0G?d$@K5tY{*f{f(;s{WJ8}K z&8YWYJ=K#aOM?8uf5zovH37k7^6ntWm`k1~xVcX7HG4VJ)*+Ckvi+sL*@Ed>LZ#hU zAUH8d4>>BWAz2YI1-c=FpFEOst1-o|LMv?C=Tyr3N6uKRouRF zE9<2#~v@Y37DG3U|2qYg6lQmBHVdr2>0aG=Ujtr_ylv z;OFJ!=MjFee|Zr%45~7hwiwY{i$XNZhzXSf-L>?35oMwC$BN+L=w*6WgFs1DrT|9J zrQC0kRv?fheO#2h!N5|Rvd3kE5tFFz>7adD@+#=z1blc#EE+^gcu%%Q)j-m@vX+o_ zM{R>qCVT%E;y<3#Rg0{Ia(=oFta*sBkUl%Bjmrosf85!<99TNVL^=$1PIwd3S3@<@ zygkc`6_Fzta5JF5%mV>mWTVD>tMnlvW3N9Hc~f~0vty972JGsI4Vo?U7&ULrqssgC z&fIZk)V;c_1o}VmO|5aN#V=*5bd>y0^Z1H^LX^ejgt?-%?SxNzXWAHd#ICO>rytRy+Bh0uXdfA2^LbQ6CU@^{YAbt8&zw$f8G zoO8`E4+jw7_OO*mxjjRp;A2hV;1#=zoOQAf;gD}N>g9F*qAN#if0(&NSz6>3Vh+R!`?$5=Fll)*bVF__ zj{Uk#uWkB+m~h7|vv{5IRJT|d3<|Nt)=Ym{(X}rB`&OcDLb#0+?A+d_0~-C)K4M3& zHaJ#HTvDnYF*u}3?>U1r(p#L3%s&y|R3bLjLLH7=*{QOx@OJuu+dId(%r%=6o}ERZ zf1apoF=^mXQeBvQugVNRrkU97V+Orm-f*)eFpjOsphk-Qw|ph$9l8|pX!r(;na~k4 zAq+~Z#5s`Tg*HsHVNVQSu`c@{BZOP*ZPX4jx$}#*w!l6-!$jl8j~qA;J9Mm%L=wAX zCOVd^`^7)Q5y0dx6>YYDJ>^}f#>wMqf5Wa0iK~f`BFVg{W@?eZ7-Kyk z&mlPR3MlF2KS^lNpZ?J};lC>wV|rfuN20;~v%7#92VBKi>~$mfd$kB)Gzvf>rTMU3AojN0-y8-{UXO8rvZI5@c=mtr);pE zp7n+`xL&{#OCJg~`nR@JOPDt)dQ5X-c&6IXn4rU=U@%VDwUorB)nCYpfBGv@paPx7 znjBHfwU)9Ji=7K7$%B0|maw+#~v z@x+;TK=n}GXqOOmnjz~BC>2?b!VT*Q;$Pu~=|`Hd7g7~II1?QE7Hu!)1H+4$)pl!dFs$DVa4-W=f2m%~M-5!J)#D@g_=P&$WeMOm5Rs#T4#&Sj&gmfq&lGN| zc6NVWE5C^J?Wb6^0B5q!{ykno{TOG&V#j7?+WcR!BAE8nlC5Hkpqc$Z-Upt#{Tm1L zYx7m}k=IWWqBo7!T;FV0^~<@q*jIVAL78S$mcF(h(g^L%7cBK3e{MV$cJpd_^JUYq z@_vJrY63?okJpJ}ZHC$Mosq{P@AQ@&<90Xq)f6vj?Zgw>E*0SURpH6}oX#5NxE^n) zubCUC!a;EQLB3ePG3##M28tB#>HFfeVGJAo{Z6v(ZKUWKMKdT`HATs>bAbjyNsjUU z)3;@rqb-|^^zC7ce@X`c!n&&pAmNb-mcCnM;*EB9evDH3-klbbRGL<2&1e{*I1Cj^ zyON2hSG7gUI=a1`ro}sb!t(z1mV7H)xBT)!UQVKyB<=5R$I8gX!9yI*wE@DE_>H&H z+@beLQFh2I$_yNesc9dw&~6r)-t{AJ4{xL51d?Rd9>1NAe|))&zMS7-$F&o!NU@?i zpjcll(aqev{-t1(j$+gkKk5nlG2TSe*;*z>Hdoe6r+68EWwRhqxdoPy?b$ffDO_mx z0>Rlj@}hNSfKBTxi}(v9)CqpQ#2&oxB7sX3>Cv`qCV0SS!2_RbG;z^c?$-)GICr@I zd6t_&WIyc`-~o}cF0z@5Vk+SXXAXwi;&W%4A3 z(`F2`xq_EC$ey(@6cx?T3si|Y9Lq89f$j+bvF$0m%X;~4nxhID$2K`Gm7 z&ix)dY+wNH9KlK4XRu^#U~9V&jLOO;*^_5es>zP? zU2v}q7|P}^XH_$^-+bbTuY=@jgrgWc6&~;D{GIM=>tFWStlr<7vw6C|xj36u{w8(* z8XwIwXhEw4M?jvh@cHZcR+R4OdhsJ_zkL|$_{X$s(V$S?Cmkb)4pSt`2YXRsqUoXz zYWa9)f755OvwQ3K)cE4t-%fZAG_!6_#C~&C55Za72o$W&J|L(s1#w`Y&VULYstjgt zpz>^g37?z@2(Gr$l+n!Ds3itlW{U`=tzsOGLjdkFi@z25J7f=H=eTA)okOtR^f%9B z)G0KqTw6N&zjoFYFs&Q;tAF^{bM|YnwwoeKe~;ObMLRRbZ1tUeMbKiH^a*EKxW&yS z5QBm{I9D^E3%1s`me=yrb+2XpS^}G10^o96J}Sl9sj7nByA2OV=ymk3^x7BiN#D|} z==Z@9tq&m0&kty}Gzwy+QOG*1fq&CFNIGz-+$ebnj#n*krq?o_)!b*3ULMzHRwzuS zf6CU3_W~YorSxX*^J6WET=8^gKkXmo>2V}cEh8a{XL)hrCiN>;Go%RY2GuHZZj4u~ zEu|?(>Cu8g9^bJpd3icnF!uBNZM4^$MR_$__>qn*t*ioNDX>`h#@5psYV4Q@(!rOA ze$L79u&O|HHN;kFWy&~-rH|hkYKJ&tN+10 z=tX<5E+QHIKe)CBIltkJbN|owe_%^YKfJF}b^QnXsvhqv|M&ZG&&lfx6@aH=t zTc`g0a`s)^#nku!(W}49|5y`?r)Q` zFwlQI3oW2-{Q7o=l8g7+9UCV3s>TmIWH8I9`ak+Ak7EXe}9|X<-m~d z=>2=P{kMCc;c)JnbKLo{@P=F8dArBnCjU3)wrkwQ>=vUdjdA;|SY8LzUlWW3JmP;r z!>|Lv;2?DGf}ZwZvdxE8a-{c!L8SH5RJyYhH~Q^81UKxoV%CSlOxy81MD3y44qq9c zJfi6?*-bc3bvo8|X>qN!f6l+J=N|aysWqGR493urAQx`nb0@8F4{p+;s`w916|=}~ z1L<%Qr~O%cG#VWJRCr9Z!1BxUeCH#Z&bj{g->%;y4de~qTD70r zI#YS^G1vFsmTa;AU6U?pa&~a8jhm+~J5EmBP^OaYWt6p~{!d<;f3bxepyR}od3Bh{ zZXx4OsWLwutcz`Je@{ zOZ@Ly8u7^Thyd>>e=&s&Nf+J2BCrI87tx{}SvqrGoJh6^|FRE;KoC3DM1+#-0%0@4 z=S$?C>;{1Ux8wiowPG(sya;r{ z$?w_xzwc3e9RC0IT^alTFC5$#(} zvvFB~_@LH%RKUMaM~_G90paQWVT#iaG@M9$Z?RPAL@xeK5`Ngx9fdwP`v(0Fze!yX zz--(drTE<6m4}V*lMXJXI!*()#E<5n8JT#04V#zg0=+0*AnCb#k)KIb+L=^+gN@+5 zPOEULNu`6hf1Pw%EbnJKZQL1+Z;C4Zd|SNC;OCnReyL$2{x~gdFLG8|zokjPH?T?$ z2PiqRACBdrm1xk95)IDq5?!B5$;vpIH~&`^KbrGa?3p-2_RoAX&O4UFRPGK@AN|+8 zq)5w!^|GrFMK9*1k;0$>iI!8x73FEk6eXfiHvKV0e?1Bqs>;*B$R7DfMn1B}GnR)F zyW~_J4vN;I4JFs#VyLWaibKh-w)JCIOUecqXQeZF_*QAl8#C*f679IeY}AO|n&;Ao z#mJhNrRnX^8p2f8er1nqEhRUjhKbDJ*ks>{y$x0>efPU$ZdK@mF7!g0y(1(pq6_+1 zDb}J~e{P|eCm$M)bx=Xdtn9*)amzJ|y{*)4E>fl~Ko=Kk*s*e^rS71POy7axL|6-Y z3tzoy3pji$ovT^FbWEnUCx)rbDk8L<_eT%UGi`e^$$-NDC7$I%b~$Pe8E0$BAdDvp{iQ zjgD(uiMA@~msH|*x^_7+%@MT}^iNK2EIm9eEyueS;Rn=vxr$PPNyxIv9QFyGA^dOi9hapkDrb3aOfgy zKN;QpFv5OY$sS--Hl5e!k*y|W&LJ2_rIEnL@PAI`(5z%TK%spHZ`PM-#~7G{wOVxI zG;K?3#wGuAGcQq_F+z)^`ZIIO>oQw1j?+}F?-D38PMkW730>SpL+7I5& ze}8OOK0-2i=dDD!!Wtw5{_r%!Vc|#Bgku_VX!qd;=Sx!R>@qenKgKLEvU0Bh+1i?A z5zR2UL2#PK7>54~3b&4$K~@&LAGY`OY;*s778)cUw2Z@5$PZ-2OOKw+S3;_0k@Cjz z_GRCM=lfZ2l=Y(Nk+?7<&-=DZ-d>|O`G0$AC3oMy-Wy_#M_FOLIfU~MdXok&Vx%r~ z*DF6k>N$Hs$Z46O&Ez@w+xa3%cNessL8q;~yTRY#3=LaL#+NEgs4Oyd`AhIFhZs6=}$a2ka)ViFG(=yLNDGnd*P zM!PxqJHE)0HzUetS7g9U;Nwj5JqZu+?6Jyq1omrLI&T#dpT8h)8BYJ+CXjO5!Hv!{kLGqU>U zDcNbKw@-ZMbdxg*q=2&id41xqHqzLUZ1H|so8z=t>XFKD@+#*(PN!GnE$-ZrOSkw? zx5c$NPOx|1i!%Pr5Bet0hLB&lGGF+%%-@ilP%7(grX%_Jq9*Q5dcKacUVmxCglM!w?d)-Q9a=mrDOJCQYeTVl`Ne3kn}YTXIt2`=nE}g*c}@W7#e^YLPI?9m}-;^qpyc4zox}?gLi6>0kTo zUqDIIuceGABYkURzr?@cPwejgtL(NGY)`jR1{s_69YW1pB{sNtw|}!cVrhWP--B?9 z+=M+O&mQN_te&v4jo8NB&+rYY&&J3mS!g&r9ALm4BLYHrb&!|f;gB+fsSNEd^P0 zw~4Xd-zCSe`GYY8?sVoS)g$m)wR_?pqwPtWm1uu%vWdJ5MxhgL;ZT-`gP}Cfd4caz zoCkIOMh2GITYpZm!NFT2j_ca?Bf3EX<@lY#-DmF)mTBQXd*pqX4`u(G!H>o|!jFD8 zi%2iKL>@8)6>Y5j-`ZH(5Sp;Dce6gyxN(Cpb01Zl`;&@&Q`>jP^t5H^u)E3C%tmH9 z6H=%zqiyr%rn78RY|!_4b6pXS**L zTpzya%r|qNf?z&i3@*?8FU11=T=M877OppPI3dk zUXGK}r5I)DT9xybIch%P1zt^ff!7mW;LYT_1t#uAlw572Gr+9thtVfLp3K+*v@?}N zob;QaFsA%Md*(Z{DwXF1uXDLLa}g_~nW`!wE`L8Ux=zTYMB};~H6vnYgM^;SZspnW z(%Lk0@pUVk=U#tqkmj^2_p%`hiFyR)E##rV$+~Dvn*&-y{ULaD=j6N9?=khTRv%;vkUQvw`(=Dd8Xv%5J z?0;v9I(3>Ux?s;UMKxq*>i%b%ppVwsuOO5(dG^bPAl~GRqrEVukb^RGK&G28;_Z#Z zNc{|q^lBzP8bODQI+wfVcn_6dCjpE$f1-piQw>LxC7PEl+~#PO8;G&*+kyW-ySxpV z9N@v6c6Gs}A$l-g`#%zdVMy?_;{hn4P>@Z#9_`Ciae$l3-$ExUUB`O zT=7F15a!uo8*}SKGB&apXlt8Pjqe>o#^0y$1VS@ zR_2A&2~Ext(Xy`aq9<${321IcAk_bo*zCDG_1(owV%BdsM~X`)DQi6b;;(>c;D4hw zyXR7W!cO?JWBsoQ-t9?jUu98xxmJX+vso(`C6E6l4Vv*=yx#MQxLPyHQOHd>f53`5 z?Gca7`{a3YBE6zP&&i8o5w0R#Lc70n09$T6B@coeDQZ~>iW+hTX+2g(0s9T)zr=2F zP7QLm9Qc3Y;~0+Pws1hsR6!X1tAES+WyryC7(~gK2?1Q?IG3#KN-oLnx}LUdc9}0BRiFQXP1Ye|e`|C$ zG8S}o#)(_Jcjv0c&ga#?L!gXivjKI(ub=Ixqw-FXV!g6ckLEDJr=`wu5q||ZW<77& zZ@~ZM*wZ3aKjdYZWLY@4X{`!3-zXAcPf17dP1;Sg?AI+7dnh{ZnRPGi)kC6~t_w(i zOzKwOk~)8^zSV1*TC)emxs(P+^^R057612J#dn?m&aDstMhpwuB)2oi(qTvdlOBH2 zC#U{Y^?UCaZJIC`$SidSF@H1o{4?sckUf!2?g{&-8sAYI)v9e;TAvg-0PjxW5`--H zNzv4uPU;uyEw?B2gGff_+o!v{CLk6+ifC+!0_tO@jD)=W+koyp$V04Mi8;8C6DR}k zp*=ncWUnnRIo-0L*jVyXNIed$0juhD^9L~ojhoKsdwdnL;|MIiyMH3)7@14Np?{QS+A zn=4`u#Bwyn7E_PUfL@3?+=|H*(x>z%OTR-xBS&PtH@n0msRX} zna?T?VJ&18-<54)SAR_f=GzTCH<^P=gL|E({tI_iq@pr@PNgii<%uo@Zy$-30Um}gzPKV3<2k$?2;BCsp+PVgkFPt>_| z0`JNjt9c`e{kkjV{l9Ke@%~^>rt>T~jS9$uJuWC_^di*lMn*Ws^gE76M&5xAfA6a&2xTSQM zox6YU!7$sHmVdhh&jaeU_uAoI|A>&&vV@$L5ptTICAYTOCp4$D@;RbFB$#Spc1Jw* z@K3m!Jp~mwi9=W z*Q$OuO&? zIOF$w3&`izXoCL2_$5}-uLHXcinaesLzTF(XsEA0-$3lLpS*$0t}#5*Zyz+N{EeMb?hW73j&406P1I)Zc**&E={g;rRz<^wbmIY*ajdO>ocV|Z4% ziB9%^_kRcM%^S7<5Xlt(_(IJOHGPvC>TfPoGb6GTEwdDVaJTyN+Rt~Z|C_tD@&^n0 zLM=T-6S9cGTf*9xi=X0Y^j>Wb-_ICeUcwohCueNL8mHXo%8Y$CS!UlJlkq)pfS+EU zymT~qW=zBV1rX9`w-s$VN)b|+!aL?~yZ?zf^dh!l zhRHalaqAz_;2Vmo+}g#a%Y@$kl(yMMsGo3D|(^*x=`uXQVHcHrO@{Kb<;fiuBa z4Q&nWc&6#Pp3E*i>KHEnaZ~aQmR@)?%zu|wIHi6!2jo&QbfvbUih%isYI^(EZ#f-F zkfl7^cqYtcJi?FqJu$N7T(i|?t~tDZJJ$=^6T7)K8RQ@An&|HHKl#XKf!rRHhOSjY z*Uy{(4%?aV#UZLrO42Wsg?c4+Ft4l&@Z7gwau#vwGlvlMtmmUoYi8U%N6K*7yd6?Bn3(Ypqg=Wz`ztDUL3k%UBdJAFOs|oNqr~B}Aa1pi~XG&iG z-;lshDyEh~KtV4#X7umVOEXUerkB6|AH9s}r2uUG4SLC40C4U%1nKaX2-12iese1( zyPxC4Nu=cDJ}_hSd%}6Fy4K_gGJn|6p=&zB4MifhoY6+l|F4iK8ak1w%IbfHOu-&2 zMa?>_#;)zEFUd#$5|-N+RXWJrR+9*j+tLDsWNxcxOy;&BM;XuZxfM_HfFZJgJK;LU zUuUol?9iac)Mujqr*~s^LJC-ce~WYiiE<|3zHP@Kh7|hgpF_gQB#e}}7R)4J!ffv0`hEs;3hV#W7*EN=@0hd5kVfm2V~0=*|`{2S9=Rt|_UvVCh*BPXo^0G!*q zf{%2qI>HQlp&p#s`lLBhet)bkW?_)Lc_C{Cl4XqTam9n?2`C-xv!7nnFSn(R&5lu5 zR*7qVt11(|c^uiI3HdfQ0aAozB;<~li3l~gM<6Wi)2^b(@^Adn1W% zkcey0z}Z>KDOr9(jm3%%&Cg!VJL4ubZ*2!E!4FqcdBHRLtu z46&*Y~lfd!IzGG1oj}v&j%9_Ek&UrI_b#{0TBe*H!OhmJqbg_mJ z#rxv?wfiT|Up_m3xwd_OeAXoL&(0k9I6pK0zBubg`yP~a=v)kht&!#beZF*k%a;z@ zYsJh<-u(gwbow_>=YKw<*~d7;SQ_UHbLW|izCSkwc*IA>6VCI^5)`|%HW{Q%*T)m+ z`z9r;98ytGxpGF6^|+GJcWh}Z!+)EoF+1qBDJZI-3E#b{oTdJsR%-dNA_zDNPA|g& z*WDQ2n~1_VRl8h)CQ;T4?cfdwRNb;@2Y2l2uG1RWgfD_m;eXhvOk^ln7 z@MAcLH%i!>mw#;0w?TQ*Zn-G3Z;64B+-1o(kURzNWd}5#P|E8&NAG4!aZ%p%3Sbqf zJ7QF#2jCD~4aaYCUX(^~9rDBiRPx43;N)Y>pe6;kV?)rstGE-D0aC;ZAw^_e06Xjf zq`YK;=u2AI8T(58b%ZLxiG!TYRxiO&l8u{DKmqmF+JE3j8O$;ZaVc^SCOC-Mxo#j4 zM()N8;f=ig%7RUC#1KjiPNJp-{fKa@AhRDA3Q zu7O%GW3|=S$LqD?46SC2Z&s8)Ee{-e!!3R0Z0tADz~k4f>@EPsg4GLLVRs1+u?6z~ zAQtNxTz@DaMi5`#->)rKaQ!PapzYawnwG?%H-5!#{uua(xzp<7lK9#wkxZ%B%+KS$vf z@%76sr=DL<1SoRJS_WcY!-H2|N>c4l>){;6o`1rams=hd$MQXA$&J33G|~cJNlusHN zwgPLUgX~@5uNSi9en|@7{Ji*@?wl`=Sfzvv0%NO=w~)#FQe&|FZ={*;T50B|f1YN( zH#$XG%wLFUFOC}5(#-R4Bvt%)`PcH9cYiop)Qw|u)>h877|d&P;6T`^LN^+cH9kE~ zpa!=LU@(2#ar~^EHvYx&4kk0aovJ-#_^e;f%a3{D{om$^f1^-|WR2ftjentdJ}F9v zB0Oui1I``UHS=AUr18T^a-cHb=+xGwWb<}X;h*O^q-jMGmqxcp5I;GJY@EK5A%DJt zWS__o?^=Y!WQdmn-J`+6We(|a!7Q@Von~t=!?QdDP_FKBYv+bvZ0k``!l^=TcvCjN zw{pYZv!EZVTSM{r%8`f$2%_!Zswga&u3XMNg>}h zh`k?sI#{oND}nq`NhKcVvPe z$d-z?LZ3X*=~jwo&0A}6itCe8+&Pmtv$>LB|FW@NB0xBqU&!&UMM1Y%gVv94zEdnv z9IiXxiGmy6s%E>EXjCDWfPcJJyQp&4tIp9JKpw0r`GJ< zW3**0Q%EX}LR)e$UPaGmsJ(kaL@zLc2Wki|heJ8nwd_K|aIsFX9C%FrbuVu&9(g%z zB^%CbXpQ8|%V^fgGoSQeio3-gYP+h6SG=`^lYM>?pTG!>YpzDTbAR^=80l1Se~PyP zCF*3X=>5fc1tf0OVisB?9-2GhPdBdr5UU@i>U?7z=K)ROV~IM}-;1A<;igH$+7B;V z+_7?P%_agPPxn@pv8DA~XQ#?$;o9i~xVId8gaV%G*(pf2P*c}pBCz;W7X}f^&5q3x z^l>(h*UpCiToxq~^M3~FmzzW<_9J}6njv+%vx}DIEaJ5$gBoF5zU3=1588G7yf*x& z#gyuZDHTSyRpNN{c;bcEZ5cM#@TY6GK@%vV=cK%iI&JF$gV`}Kn03Hl9##B^C?%J_WrAZ8Igem&(QZ&iIa*?O0J5`XKt!+!^Ar9}VYu$~s4 zy5UP{Jfyij+Q+MKH+kt_c`#Rd-%1{`wKIv#Tv{>w=sig$5#s-gi#n$R(35@LDnC`$ zkCU=KX8Mkg`}q~K0eM|2@=%_uS^Db*r5THL&bV$(;cZ)fdXrnWv1kfk5Lik|E{fR*H`P~B{c0+JZ)}opz+C%5 z8pGhF4SUxH{0elgktO#oT=GViJ)47*+m>f7r!jOL;#Wp$foTqw_zTu`fj&a3KSYXM zk<6DfWq)!I219iif_~LvU|Dv9uljk2JuMkLat-yyBWAl>UbMu5r61C@4C5v6N#_ph zAXlgXBs2|2eAzCk@E7g61rwCsallE&tGshNIEUC5rvdNpxAUN8oDV`yoEhytEBo~k z%FW^&Dws@@G&~=bw1B<8z?mi_>T-XwcGIoQaeu}t3ztsDLRS|&5GNJ>O)0)LDM1Ft znq}z8-WlAr+z zn1A|LDHaUQa0=2iePcC5U~f0ccqJgSXi^} zC|k#VdJFI24D=`y#es%Xwa)Mr)SYDDFn2t;2*Y@G+TO0H6OEP59xwyp*Vb9@_@3zC z3%1;Zgg87lsXNm??$-b$B^PoriPp1?xM%s*H$7=`N(ccU2no$tyd!AXs~j{2|9={| z;ZnF~uy4J^0<=1VDof7?CwQ0WH76e)4m zS)Ad2ox;yfdX=>YL>Wez%M^l@Q-33M8rr1cOp(YO!pqEiH!CKw0{&W?w)zK~R>KGo zY^IIqz7TRQw4Ya*8Gqjf1@*5* z*w)j0$^<$*5cKn5F=FNhDvki`1z(-hDzgBc4N|3j(-pm~7vPK96}rIvuNH+##BM_3 z5k6fXg?#W=Pum;a8G`^PpZ3>z79XOJgp{dguCvAtZQ<5R;T}Cy`Hp%%!d5KXw8{7) zN1eV&K4dF)yk9dr_qz={X@5BS7xpV~L(DeSX-;D21l3>vj}`lWtl0l@R&29uT(Dx> zW5Z&_HphmDm>*PcgnI9Bl;JoZ!Xf}}k zY*v8F%P+p~rWai|jDPAmr=fp=G~E|96H&48%w7<^_R-sr2YT^jS4Fb&8rnb^W!U0Q zdAHF%+$yN>f~@S80hI0cQ)%K*s>Nmk@)8Kxqd`DMXAP6jQ$Nk+i^;4ZiMHVWM{`)W zHc1~ji?qAX*Z$hXYIELB%3`M0@=JQ!8t1{1Emm@J+R63IWPkm?ycdyO1fhrE1jlfA zVi3iRq!xRY~ zzjf8h+AM0ALHvF!%F| zgoAlth9IEX(SRC?icR8T6G}!BK6)W0o1ZM$Gb^Bb?th3UGgk0&nJkgvJCYvTa8&QE zG0PpAWj4m(_ejx$Hc5J%0*UaLu<2NRv{Bf5`K9Kx@;Vz{Wpr(1M41rhYeKFWJ$8pf zMmlh+Q|$J_%*+FuvWh|?D>Lkf4R@Z>&dQ6@%YF&{ts6@hd1Pc} z{emZcnSa3eFg13jIPbwWBSpo45#G?*_|E6_vE1sa2r(3UmOR@6$i# z_`2<%_%AU-fyvC}8o^vY#V(c~AZ_Vw!ZhwL<$+|;Z=hFwWgr{(3;WabSxDiJaSZ%$56 zsvqJrSKY{7nYbZ^;*`Ea<(TgaE__5bxPOjI8wEI+YypQYb3m+Cc_IZSOhJ|^3tzxy zYJ$k*X%Q$SlOhqNkN~D9Xd*Xh zLkPGirwP#LEL0_Ia;NA97#?|_`jv4#F^qGQ?~8%TA$o-?q)kMcoX0% z{+jUB^<28K3jYpR#r&EmNbQEt^;VmPPwW7q-7|vXO-F9XQhiAe4?+*eDbUJ)EnLSR z>iq(G;LQS){GMo%8t6H`TsLQSo6te|(>|gdIi1WYvWK4b*GrP+M3&jY8h_1AbP=kp zeRfgBdo%6@`_9Yz8e{CDz|@+U4=E55-#4Sn-Y*(oIuuL#rI2KQn4;se|NC3)gmqe| zvs5gUqDz_-eH2CVz6M{sd<{8I4mQ!y;)xDjd`{SaO}Lph`UIsqf0=U~C+FJV_8kwm zIqsN2p>}!8EPotBTFl5PCVvk4CU4F$vA;XO?ewaAxrDdMtd$txY7PA_6NeRYj2GCc z#Y@O- zh>L^K{I-b?qY)dk)#TOMA5*rbU?z^gn+fu=bN-AyT#s#{sL!6&rpp9f{95jfn&hWF zncG75kw=;|zPn!tjx0Nmn_)lZS(51zmU^h|FR37sJ?pBqD=0WIc{wdk4J48tFXL-~ zRFj(d=&krk#?EscHFZegh*6ks9q;9^NnWyk|4ly<$=>>0T`9$B;J1y8|m!|IFmS zcb?lcGh}+U2M-t|pL9r{3dfoVwnW^vvN1P#WKy^G-<%Yr&^&4gYI@3=dVm z0Hcs!hAycnHoRR~Oi(M&RKlm}htFB37Vi1Ezsc9H_N1c4m7jaEy{KvdcG+LIe(Z^u z_DAZ6?@d?M-+y)`m6(*{sqt4PBPEk@;y!Qo6SoFW3JX8q}7kjPQV{s z`N}j~^{81*if9t$#`(sDQp))kfo`;_5ycP_PYwoG%YVd^m*6dEw{mHC_njV@GH%>6 z2hcm2M`lJ!tW7AoSv<`>@?K)dj+=Z`@(qEfx+TS=GXGzvhHi{?HQ)Hl>b6{-srX9e zG1QzYJisUG=1=LI{l|t=K+RP)c>)z%_ zx%_%Rp2l`BZwesw)MmiFnndDa|$LAT7RldEh^?4etT4?#|5xeiBCU<9OW}H z>MbKU@d+u5_I+_uktZs$#gwZ}wNuQ9icDs~Mg~9Sov+!y?9rWXtmcuc?_}RDw@Vmv3HCLV7}SFqkqB72xc0sHtLOTHpQf+ za*cS>MDMYb!Myn+$Itcq2#l99(R}7GONoy>CVi$aW_p{B zf2N!2xdB&6`jXuKp}a>mUwUY&uYVc>VL;a40v4D))A#gMMiwo~Gv~DCdpugUA7Ovx{dTS&1frn5MiGZ+dZGr*c^P0KT1d7<9}fbW7m^V zx&@?t<;W7muj-L~EI&>tzEstUpExC3j(~g2WwiD95Q@oNx??x&B1?#DEuJ8{FK+mT z2+8Xt`T??h%Nu{nxt6q(fpYV$oPqSdYI6T7fDB;8yW>@}I>Iq;SD2Y3OQd#+dZdnN zzLB08V1cwkIy{q@ni=@PkAE`eopv9>MA)7j^#wYx6JkxSzB|Y71~NPlLDFC7t%P<$ z`Y*tlxxkaLRI>RzjAROZO&64slyO2tq|!-@mgu7eFFh7hl@C@nlo5xVVgtJy@Dk7+ zT>ZkAFX+v7C~ru~u90!Vxa*ldY}i)fWD>Op^j@-0&h{L#lV?*fyniNXkO8J3(M%vH z_8(Y}6xQP{JFbg2H%)H-!Saa6JYXly_t>aVCiSVXV?AIInKppyj%x`HlsepfH!M)f zaKZF=5pouWVJ#I%PgQr||2hW-TcE9OIgnrw(ejcNnu@0xc`7Mpnny++#boasju!hpf?e%jBTd;&L&0xGY&g~4G~I$Egnx-ys4YN8hSohlr~q1N zh`)aE%t59ho!EGK-*63B$6t`XDn|UMiUe~~5@VSH+u)=PyHIRkGYpIT;G{-H$fQhv zvVLry?WXzO5LSMWVQkFvqh26BQ#TX+{CVBRy>g@PhZ|?g7 z@yUixj;qKuu77$kd>E&Nj-f7e8i%g+G9#`E{IV|+LY>h)eMxIG#%Mb-$X3ie9mDW6v9MuPQb4#)7{CzyYqU4LMQ9oM3bUc+of{+qGKLqW3s zN+bhl(hE)fgVo=5hWU<<;@U>7X%5&0l$6R;)o>`v*{S7s2OhVan476|w6unD7!ko_ zkzuuTrEWd-ZcN@+@;hugt}gGDJ@$671WY6IoIuj~xK||Z{#<5x8#0=k$;Yob%_SdB zQ1T$h@nZd&fVi9u8$yRQUI|EWdzA+OKqMg1q<-){OafB5T$4PAkzaye2%n8u`NKuV z2mPhUa3UcjaDRM>M!04H@$I}$ENpKKkUK6<+(T{5i-2of)Qj$SGskm3RjD!Qn#5Q4=H?zN>$LLu1@V(^=K>O7v5p*2{1|y?;>!8cK+&%vE8_O!)n91A;o(z*Ja0 zN>uVj94Y87pUZd`8yx>_3A=JvasjEfmI4)g-Htq&Lix9ZxSykZb1Ff$E(!{z83emC z680UdUD)^5*lFFU@s<%Sj^CdBNd@xI6n~>VcyajWXy_;g*B$tcw|%}L7b(?s0J1vI z#D7E$XUrwMA0YqESR}U1_oNQz9|vuM_F4t@s%y*jlv^9>#~Ofixo(l$F))8$OK@}_ zXee=tfHZ3!pT#9 zUU_ISe614vnD{emJGS=~mOP)$Qrpj^t&p}Xupyq0CCDztDiHyHiD38wl=|KQBcGJ-Vb6(L znAHsxQD}&U`BYM(TMMFHq}kU6i*}N%k1*ZNt2i~YYCZZLm`FmL*iZm8Cx3Qcgme9- z3;ihjxL`>;*(~^m1xtj#STSJUt%avZ-Ak4@C^bgxDkS>7ENp7Q0e^dI#B>N^X=w#B z90YzIH@u-+^x-K zJ8~doue1UMI%id)2L}dyBY$7jro@jl%Q*~g!JZfnv>ag2I^zQo?qKP~d-8w@>K_L* z2lcf&AoSwr{^g&rYFE1x3~|h!e_D_kXbI!dNz^VoL=D95xN~(jxH*^qy6b#p#iIF3 zb;TSA>o}aZRhhfttg%+krYyJbw%o9cb+OPS5@yUPRf{aytiF>?jeh}240J0cMnxxo z%|7^M%y7<|=)j#}!Pd5f<;rLQBOohb+sL_H_{W0dGm`GZLcCtqXZBzgW@Cd0{_eWK zrC!hDL{uK;v}>}wIo{|VmSyNq14yNe0O_*YZXQoxId|IU9Lxn znCaSiaJ7riLfHPOMt@)`@g1EHsY&A>ck$?2J=_+qRwzzdf7nCuQ=|(0`Sl9_(vYjA zx;5tE@aiN+XXj69EWYCAfM43%W6!=H7v8l-I6(V% zjm!j%019w+-Cg?Y>r4Mf(_kvh>u4IP{_=W-g2M2}RVr*2qBC6eW$9{_;>G%B6`r+; zV%J$;h}S}8%1lcn)=--rY?ROKR};Gsa-usoR`O&MuL+b}@*H%NSsroShjTu%U+%TV z-Rwn|gTCmZo=;e3G*kHjTi{-2eSfKS=NHsQ_APC1A6uWb#VFIrV zYn&_z8n%fBTpIAf+cQqhC8>^@^R#4&5!Vl4^ADUEDPYTWEm)e^SoGw^?ir18g=n{z zvUEqDH}i5ns7VG%A7+ARGx(*9f^!1P4w<+Kc9BB3VEdC*V#`&c;(#hP>3<8CUc6&Q zCDvbm+(Q~OTSo9#ntSxKc|gG5R85!3pt97i5rwqsr*v{S^3)7|u!p+N5px|)HE*~! zvUXvgSo+MZNPE->i?CMp?ReGBzgabk4Hycx9#uuN1vNx_4859hurPBfqYCmBX4Jc8 zIWYo%?QxLtaNqdLi^`UyD}RgXVNn+>>$~mozVS_WqreTw5`m>IHocyfh;PzIZEul) z9iwAPF=2oEkrLRP;>E&mIqEhT=RAA;x4izmZ^Y(yu|bB)Ov-7{5Zf_3a?=9M+JCy( z>?6F3D`ILlxVrdrHy%`puhX|z=wHoVo*)SQe%naw+{NCtl%Y#e+JBW`aqWl-m%5!Q z*8im6R38~>CRLCU75A%xe!c(4`(=y)op1};{fdDE_HiSuEhW)WUFmWPUH(jVxxk7Y zeLpxPFOCXsvjp@&rSR>vG4Peq<6P*4?2 z<2ke!q*$w;5BLC$v59vuz0!D>rFg zAz2<1rI5S`$ugZi4eJT=BF|gXor@r(Oat+=su%_#JxcxyfiVt+3=$?Uby!2x=g17+Rg zua^=R-6}YErc5UU$9Ihpa+=kkqOX+)b z53b}v4nlV82z{)-3)hs|`y@HR@~PoW==$9h&z=*GOUPI_Pay~fMwFY2s+(xid-}Ex zFA56d=gE-(*nc;ewXFTP{AoWLZT8{yAJ3Wh)12vF^4!b8xgybzrsL(+36X+DG}9hR z`9X?781^bB?SGjOKZb_;D>LE`*7^#^b!}%J;w~|0E{4`EU+HSc2)368tAc|yQR4sg zlsp~A&MpbI#8A~diqWvL@U8NapD8X%>K*H@+`tX{27f8;`4Nx*rG_Vh5j_wexwi3= z%nguxq>hYZYdQJg>-&SD_!MP@Psl7`$vhffX@{&;j^txu$zf1W4wMB&n zz9tX3&C`_;`|Pn&3k(5C?RgX434n-K_x9%^bfGJwp6IK#nt;Y-9M zLQ`Qw%YQBq!dwT{A1>ewHn$qHBqa@$y88c+k_Vqh2}4yM-au^`w_q!&~C zMK&$3P~mZ8V!jCpX(ao+xhi`O#PM2u@@b4v|a;=YlUBu=`4t!`V=AkP5X81sZMV%T^Mqy z+O;;9wdoGVo6N%hQh=j1jNrmO@Ru(02I-6Av>KPdh!G%9QixeZ2zMN8uvW)ie5y#? zy-Co%NUD-fPuYqbl4~ap1scHv#?Kpq(=-}`3JA{gEmF)NR;+4@wM=wEY9K723l1y1%~~asXC8ked)jZ*O=QS(C25f-e(!T_{ld5mjyrJqe|28P`y_`U^`(+d z4w3fVJgVs&c2G$jcT8lTjd$S1K3dlhEmL(b&!;(w^KTZB=B*XM8)x7@{^i_a9uxY2 z5yJZis*yZC3#6EC5vSmG609@g4_$uEOZHnsEjeP8OA}Q|> zXUE|5Tu;ZtwN+fUAa;vHGS64o*Cub9M#R2Sa*J>oZq}0V%y6#soH3H}HJf$K zs^~Zz;Ow#=*ApM+8)kUGOwn3N;W#!f&yE5a ziH+mVhy%7ye|fd(+o^`zXd3PW&7*iiP+w!W(K&Dz&Bv(|)GcfGs;T5Bw(gsuTtCSA z1_P5%|7c*}@OeME1<~Hws0n?aEOe zLI$qjD7Vh$D0hr&TV^PXkXtWhoupiGE<^FJsXitJ@=qFfChK;@$o&Rw|V=+T9k4h97Za(y(^v7Mt;L7dV^mtu?&F@N?lz324A;i(t< zcW)2BDkMIfswKhzQ*en9gD#SYU5VswpIEsL6>75h zE41}YdQ~|1D6>o_P1I|K-S$Fv96O8 zkekLO+nZHDGlCr^q<=TBGDG9-$^xxM`=lrHcUu5PCw`6L0N*lNF!^Mu_GJoE(G7b? zTLtbJXpc8;v+-qjMS4K&-t52o0D)RWt)39$8jLxiHQ@JVc4TG6j=9{KFiYP!T6HRj zD@(fAZ?J)b?26ZXPP(46j^fPVPL}OB>|VZJf?`&{mG`D;*MEd86Q3s%Yf{|qbYA=Fl7H!vZTsze67J}^ zgDT$nbhARpFX zIRtyR<}Gdz?Ergc*1~LuhbR^-7?Ne6{+u4NgU@}A@ti|ax`yj)$ToKDBi1jE#UFnT zBmSa*&{S>QBTg~`%NZ%qUmSPXFT9wJSa#1P13C4$ofyqzUXz{G7Lvo_mi*;_*hm!u zyXDvKJ%7o3;7unfUuy(Ri1d5&c5|xc5 z1!v_34l5rExx+w=n}Qp`mu`EVmkX48+1pgbw?w{a?u&8Q{rj${6W9h^*J_=7IAmYT zTOLpc0P|fTc($)RODRKe)p3O_2p=Za#A(l&LwPnJ4QURB2-eWnP-w(uf9h7KiedEx zhJQpZg2M#X-X#DO`YZfp^5!uPuj^E0x2BE~Fv9MFh(;hy0!LP@Agn)wT``{+L;MNN z^r}K{M*uU;$YYO^m7n2+$)xtC{7nS_O+d20K9vNVGDqv$Q6v;baK}>q`jlLNGq4tap^%Q=o5>nYk+_OOJBDg|YQ&RJDJsckh6M-a z2GmJWJ@OaMSUN&%cAfz&QN)BGEDK3T-qzA_6EZd`Lf*>FhIfxNm zK&JQRDtR-tIY$B~-};m8)5bR4znH8hoPF4GKg4YB^K4IEs8cSm9qf)-q#wxkpjBUk zv?E417eEVxD@m7ekr5Od=SS69cPMc#rhz<$*t;5lMqf8Mt21+Jd%Z%Jppg+Ne;%{9 z{T61>0W`_~c(al_g+_9`V12QOxd9^~KY|3EOtNTuOHCvsKbkf2oFrIZGQA8Kkik16 zL`kOXZytpoCh>IEu|z5Ja&Znaj9_3ueJ@Dc)TV*ufggeGX=rJ> zu^;EGD3OCDL53Kh!X7GS<7m@mweN_-A+?j1opxF6s^G_xAiE?jb@`CI5pz>cYkil# z*sXBmXSNs~Q=YqkNROaQ*>z@=iCqUKp|vm8tzB1;xv#)2q?H*`z=LS(r{{z!<7FyL zL|WN;g7&t`B41kNs(c=tf1{8PGn&PO=~V0R1Z~&K72oEwb|H;A$J813lojZF z1Z|1h-9dTGhdtoPz`C^e-JH>Q7M&SdwPl-eC2r&wwmL`<304zv2lg9 z0p8v<2;;1?VDjPJfAUHg5+dicC+OC!8I9J49T5iw!BFZUJ_?!{x8zs&{Fg~3XggMX z`X$a-CG-VdZVnH2af7b~o*JM}{=5=nyb3JqEX`-5mu28q@w>`EGWlBN_1b)vGI?7w zv|mBrtdW1ne~}Pr)`H8vnOG@tI>%u%q52>$x|!87Th4@`AL|aW&I7fFNB=Ji+~6c$ z1~X16quEu;vop52SDT@mv~?CV00=C@hX~>V8V)g~_))reu?_y`nVV>G$v zd77i=f2FdLUx=BNiGrzk0z~170y5$h7)0F({`&O0L!uz89U0qMZ4BZAXSHsQyGTcq zF6ZnB?%lZ&sg76=ubD`1V9$D*a|8M=!p3YZf6!#7jIlN=qo#}k&|#73t(*dJ+Z~X} zPd;qrQ+!3=6=22~D5R4$**N$sZ|TO6sw-F_KdM^+so5z>)5dys?&#w(?x=)J{ffJ? zKLmDHI2bjs`xDt9AP(4&-z7mW6;m4^bGLRH5=iV;vK>s|rQ$BbUbNQffB@$Z(n zf3}XTaaJl4Q(Z(0XAAilmCA)aZW=o zrg+eTl7`V%N9|5*Ig>zvB_JbSvPWh(?{<5Z8*a-pc)QbAboOUuWP4mUfx4B?`>^;A zMs@Ro)~CQ*svmr5niz&0DtY#=y=}5+f1ItA(PE-z4$&?(t&gjyDk$UQwgY?53Ew=Q z6LlL601ch=B84EXm~ zFDx$q3w*S+%4Y(5(spZhWa*qwoU`$$4uj_9jS!Cey#gW`5leGJ04zB7 zV(*7G!u|XR!}oCx`0Aau)^QmFZULm)6n3KF_eWTkIM)Px6BsPSAao(p(v5@j3Ho;Tlh@^zSm$lpT;zq zsN|rw<3Mz3%=XQE`F4iX0?}=m25PdYWRTcrL6NyH#?BN5t->#QRb?2p%$R^=9~@xS z!|s#M`WCEKdga;?PAdTBzFS*t4{O5TqGpEI7`ukZu^w(tuMe`NgBd*E}CA2-3_ z2}g+x8!8J=jP{}0h(YMLxNVU!=j##dtMvyqn2SQKVnY@lr%Mm|l`eT=198$Tjzx1rn?v6-&Fq_wtg^(eNim{?& zri`19cf2`_>JikCfA;^$3TOO zdt5f(&@{{NAWVk9kh4OmE1bpHD}}WZhr~%Wys66L4r^y1to_G#)_42l+u5Nlwqt3n zgaz)%Lidutb^71E=HG2t-^5tTMCT&j?@K*Dba&bOD@$qAe`UZV3QCzoywfyVR*REP z1G~7F!phowS$A0`UaY@&r!X}*Mxup;8KjkwY-eMp@DP1P25EJTQGq##jySrrXTd^& z$8v2^YYiJgbHtuLZOMb-lQ7s6VepN8hKaFWL;>+P=_p zQ+9XOZ6j;pe^QC1GU7%GRos>H7l2#PS#CU#&4RFmiprhBY%a1t__vV)fMRnT(SNFA z1acmfB~6>ahUu&-;|kwzeE3AbI(u436pdU1Wd;H3U3nZ?TMSA9G?TuYh5MU70VD*OTU1XP*guS!%W(oWED9dpmBL$sJ6I!Faj>HjizhuU(b2wjc z?W|U-G?2phc)`w){*7MtId}2zstB%CVP2Lr_b9S@dk}%4B}=eJBhFvYBc#T@5RaB< zkSB^0e_`sq&y0L^+`Q0Habmi3Gs_%{1*ujkHZBs=RYeyDWf!!agC;UsimvAl@#vu( z^>{q1IIsAGb2XR+5e)o^BpGFZGnIJH`8Q@rc?%tM@;#}C$9mB+aDZ&NwhO$`^sicy zfZMov*d;cKW_Qyv_;lguLGN0Ux>Y=0f9wJwzvs>Mp=D6y*y+qJ&?jEL$SIv= zn4@|9>o^7Fs1+ro_%c)Lf>k0jYF?BG@9vq7lNC&Y#QQEmvSm+xTtlkjf34wUjbnLb z92x8V`pWy9HIv(miSj7^$4sP^u5!F00{vdNL&OgZ#Cb{5T8&IX7pk#37e}Y5 zknM(n#0%Mi8z^Mp9QPA+qknB-ze{xag6HrdYp->Q#XS6YvDfgGLHR)PMhSCT{(AZEeJk`}M?Rs;s(ar}}=#xrr?Xgy%uD4llo% z3!f!BX0QI2R-X|fe_811XvX7g$T-CgJ944y11jjZgeW}sbm^5=;sYba|1sf11;~9T z9(~E4TtC0pDu?I@{KMxfHGM~1yPW^$mV?Zq$-+JL$r`zhD%wb)Rpi9Oul8VXn<^;V zVQkoa@H)R&7%L$^tO!$`$D^z@biR5!VyqUXy*3JhlxoIJyqnue`gnW$^ zS9D3!y+)Gie+4LiB%+>X6y2lm*MHb1ff=Wu^e-b@&mVl$C1uynmCz2(O3a%WmI1_^ zaMF=mN}w8Xd*+r(uzQ=EnD-v5#Cztw%Qo9Pnb#8~nC;!PWA+{ywJ+HFbvlSUkwL7& z1#b;oh49up^|g_m)yOp2NVp;)m4vzH_B%@IvmZXqf6t3>BTQ7^k=@jURkc|q&f%aF zHW>EjUUCVV44%Q4=L}l^L^E*$3ZKKt*k9DX8Xl8Z2N@K`2q$KoVnm2c6q*f;-`@v@ zH8d8u!137z`@uStlLF|>er0msFl61xkSn6Fm03fy-K=n4*rY5CMo@?sC5nv+Tk-2% zx7Jn8f4X2k$jm&8!5h2RjTj#QzC61KZR-`qkBb#i83vg~zTXZa z#@T3}r|QbdfcdBg>ER8Qv)d>KnDa8U?EMmU3qGljOs;pxCzPbjqgjA^pZZkfL>ukZ ze;xDRh!!l~A+8^wbBh|^nYAY*oQ`}7ruxf8LRCOcQh#veAf4{e@`I`)3+!=k9kuQP zNrD4__js&xpQ)Gs7e5}R4$f2rH&uz6Fb8s8+`3|S#UPP@iBJ;&Kkc(!~m zJWk$OP1Q7+iGy-vCv{ZofvuxjK|ST1JmkPUGf(VfJeHJL>546*TL@#4Bwci3+&Urw zS*gMQNM=~0iIr!~s=Hvz9M{`->QjYGpy^XRPClN?{{mov7*!GBSlQN9*{y9HxxGFrLjt9PU&FWy<5DxjbUy&vSm&Mu?oZf4!;UlQaT5%&5F?=s7$J#ZAM$;*~v!VBx(ql4S$fYByan^Z3BSFlo*3U}Q> zDHMk^j!_++9&vT#)C`CoP}&8XBIntO-7X4iv-c(M!^cq0tQNPmwOaO-r&3vu{d zh&Gj0#_|oFso8>+PpmphH)Ai(-gwGP@Z)3}2#d+ymwKuefC}xeE9^n{v;skY9_IM> zugL;(;TGZIpJ39NncCP!yqBifyr@wbROh5^*N0KLA)q&ri3tpe1I$-skz}6_br!o=~?Yzxc6v#np^pcFBN;b=@Q(iJbY z^%Aj#^0LhlFG+J)e~$I(&?=AtM}A{jx|Tg`q>iqS#x_9xE$#oGPOwEDU z%)qc!60--dq>91~w~R=H)MO{wj;bn!RRt)%*~G=e3B8jo+}hklDvYTW5xTuIPEsBB zKDpN&zEk(S=UK0XQy~*K&|sni^2>p5BtyWBnwIocKHF-V)1hYhA7@5DyH+zg4g>W_ zweC!7ZCXJ<_q%# zDc?0$LU2OSfx43n;QM$UJ;^haMa1g{?Xjr(%kmIs$bb8fBerO}04w|n**u%GC1-2= zcooGjK_PfU-_`;y8qfj~qV7%9?@+uw3k#NmGT!v5J;7qYRk3xh{naJTf#N~(4vOON z(5G1#HNM(`kv=Z#rX&(>n*5Gn8!tb5;okKKrpw5kvUoSy-+GpiQFo##gJBgZ`JNr7 z@}fd5aepdTz4ncQbB(3!P0o!g3L}mt8tc^nTlZ8%Xmrv4ZlFcI0|>Xj3Vye;uq|=7 z(ia{uXs4Uzq+#B^hHn4tQZr=ZpfE)sCfhWe<4SyN^u2fOY;j&wKv``xrhSleqiKI5 zWV0?v@jgxU^ztwS?$UMpF_AMkf%*aiPIS9Pu7Aik&VpT}b#n|4$jvt^w-D>*gi@Tk z=VD?yUdk8KPILp)e%6IU8xw;ZLF4!O$sf4)zg|KE%k#fg{c&vvLRK#KtjwNuuv z>E4{RGmVj4NJmN71hvGJ!Dbs1_YaAPbAJL{qnk7{7-HE-^O1K&Wju2nWN7kccz0+4<1OK(Sc$;|V$$~^dr2j#5nSB_mf15TUgVSu2i zcIg&6{!~p&Sybg7=C&4)JiC&zGUY}drh?`m`m&e(x09%|+Uye1Pqj#d;J6ok^;@Ch zbP1nI>?XN&*U)_Mr=gU7TYrUULH(l`&bWUqQKx$TN&q^{p5cY@#_EW;<5sE@9ulq7 z9T>ocnYGx%;~vl%>m`867MQ){PLyrb+yc5Ghdua~1@q@i!gp(FpnGTR$82C?%C^ca zVsf0_vI*rD-4Huoi%Ix%M{49tPeX0eXP@HkYlye6nRSU%jA z^u86fM$)u5q!%4y3Y9`pIgdb;Y0QE@qFjXHX zmc1A142WZR+5kDei>hAWH#PGjtCn`FvH^@*j~sFrS|4w+YMoS{rVjc-eM*2s?MQ$B z|7Y*bx)WD|F3}&vS&MmE_eq(Og^)4En4<8T%L5?hdHD5L5q~>U1I8{_ozq|UUAJG# z1xTq>4v{hLohcz`Qrk7K#_AG8$l!~W%E}kRa8ve4KOgP!1r;ieSz{06n~8i=Q&ah7 zwr_}5KbLP7a?MFC<(t)>&!&S~%NLt{1HA29`GQK72Bg~T<%>i3cf!pc<(rcQDFgSb<1NqL`@O;fj?OTj>ee6N9$VB zy%QzfR}J&DC+fo+c?M1(a_P+^!8h7D;Ti2@8NUgEf^py@r3)1cRU9m>%`GZR`D7(L zIrs9|pWsI7Yo8r@EcLq^R`mh`{b=I}m3grBRtiS-lrx>^H~ zXfn7Z(opmt%yw zaF2B_%gG1pb*dzHj3nv)zJPe^;T`e47dH1j6Z{J(7CF^5HH%kTs18xcn0!1k zW`gWa-hZdkY=&V;lWSB8wS@C>>&7R8KUSk-1I6u3c4Mx@Kx^_z zcV}jZMGA8Hk!SDI!jixBZ?-9!+T1F*`S)LK>hpiTsh!UTaAF5Pl1{L2+TcOSkUD?VsByar!Wzkmdj3x7va z-~&koA=4=3sgz{`Ok{Gk&v11 z4zeX$IpF9GRrX@x?Cfy2&vm_#(lj@XOHDJ^h&0W-%H(9j<}^F?+<6YZE>d23gXgp; zvrA5J3gy-+$KiVDaCKmvLB7O5L4Sxf_C_`6Y(qGly1^DY-Kr+p$sBOb*a2MeGXxO& z^_w`|rj^R8|BEA9$IDfc!_#iKuVW{s)Fiy0wo*M>&<9%3v{7D!tp-@j2-f;_B-(b5 zJiY?D_?G2`@iTLo@x1_58_4WJQAKSFvP(^Hq>U2WV`m~KK%SA1y;D4|C4Us{`sJd8 z(k{Ow1M5%{G7BC($&oBeB6qgV`6^S|CUa+}4zf0AzQ+`0HDbGJs?K#H1h**bPc!8w zuZet)*(nKf5jY=au&R-c@KP6yyUYmQ$m~)G_#j29s#P2H<+Kt37?Msvr;GG#!)cQ*JD`(*j>xa(`+O6w25iikADeO5`Oa ze=?5BO%Ezodb8v<4wG-K(>0SeT=#Zhwz*{wuQ)1vmUV@v{Qf>fphiU zjPGH^7; zkS1Pj#3{Xa+VW`fK{?}y`LlF$HH}glJe-bU6FT7s&j~a0xh`qw8$4&ZO>*_k#2tqX zFc)G)^+mGWH3~y<^ zCr;h>TB0DU9)C-Qml(GlgmN%U>Z!%lswVPV7j2|&H!o8x1|0bVsA@?v0@&xmeQ%v^ zF#z@EM<;$2OyCi2z)OgX#U-R*+D#RZwkJTCe_8uiTY51C z`ldVLRY2ylKHd#CzVRIYSZL~Ef34#I(vo*@rS-yu(tpR?vqsc69lKpfw-{;$c=CgK zGZ994uk_4wM`~l^nASn?ty!-qhynyqOgG%wu(pQ{xPB3i@~l^TB>ss8v~GxwB@~VCiVnw`A(wR= z9_2aEqgk~)ALWnHNnR3QG(;2z2XW3Y76*HLx^M~f337ti4^$1<6aDE5D|yEhBjJkd z88pDDBC5$m;%8>YR{lK+fctHZ9p~OA=KvPRfPav2lHBs>UEbNF!X?xMZE;U~w&m0r zKjGSj6}=`$kj+>PRZ+LbBesvXggQY9)-% z9)GWdnU1qn{h|ycWqFe`F3RGL9p2WPu)H3SjL?z1@2VSjrJ5B*sSqyMf?l9!gCTah zU){w37i-pwyq&nrsL%?a8=&j)Ec+#p6GMJ`JA<~nJta6a%Cl!2J5H}Zfk1#I|2X_G zuEgu?!Jb&x5)fCRcQ5}TKfpq*g%S~_#Wnt_KBGAo9 zZBY{xApsSU@yPyW7qHY4KKAXr9;An;g-)-RiGbgM|?lc@b0~xjy{Q$0Nmz{QeAU3cxti>_GcW_gmn-p*W#E# zdx{itK~BnMc(M1X*Q}m0D2KzeqbIcr_jV!_wpXA7-Ko8k0Py(2XONjU5_ZS}_$O)m zQ%#p&nRC3tOJXt}>}cSC8h(JN+<*EPx;PTLrqFt3J%~%zInt_3tq#8qPo<9N4JH3e zniYVqDneszKEX4r1YR^M)B__nQI?;re+3rqv^_Nvan^IRmbRa+rSdL$e1szF%cbO?*3ZvN zJxcm0OyKfwH(pBEyOzC(^5&~0$l?itRmcjNK3#Ky&xpxS@9p_*%0#Pe*=x#~tzw){ zkM1W%qa_i!T@M*BetHY^$bZ;3fCI<8Yg`6atAub?d$i+bIJ&M6QpHhUd05d9a#(KN z`G-|;R%Th03P2Vdv0f+9aIL+Bi{0f+t)<*>u{&vMd4Mg}($_PulGgs*oq`)PEb^V#QLRk34|s z4mte1JbNpnxeBu1hR+XY4#(}ocE>*BNBWxN>2?QcZ6%O|U90`Lo_}w=(B1Y? zrEd%O9XBWZPMah&oV(8p1@ALu5ABfE?v{(fy340ZxC!oRb!GAt;hUl8mSZh!gn~0b zOP7vNRUHn3LS533$5tRzdiu#^v=^}#S1WrT_=K=B8 zeyru7;h(DZpLC&WFDvrO43P;ozA|2CjlXSR2OH(>SF&4+p$~3tP{qOR*`BS~^WW`K zlI=96vh#{?y*M%Dg;Q8ba2T=l&Wvr5aObXo)%@vT&x(TJjeiB`ZO}G2CH5;R2w_?@ z3GVE0#Q;W-T;c;O+3IYMq@_D^OiGYdsaNSy$_3K3yg()Jh+#yG5-&Nbd*Dc8<5$1; zzV#X-oThEziu?E)3squ-sX^8`ufGDsZ&^<>dxaFAPu`UPQp0y$Hp-jyYi`+9`CJ!9 zgUpVrG@t9M^nb(-*y((99>4Qye*eP@`G?i#-E*cl$Wp3Ht>hoGbhx{E z&ZWYv`b^cLC5Aq5$E$}%gnWHpJAlB3Pj@ZWI?8Y~L^@4q^$`aQ$*K*i-r22|HKqvF z>rX1KDJXWWA;Vqkrs&7a>T*mzczjHJ&>#LAwqdi5p?@36Ci=+>pOLwye;unHB1m)= zovNO38!;sY1&k(=xpAPwPL&NrT^iPn!9bJo-QtP>C0^pm3$U7z|dTp2L1 zFF!@SBaA^2zWV1T`C*?)bY#-O@}}^^X6Gdzp7?Jx0EwxR|E^Rh=>k|efZx<2A z0(F6uyAYV)tO;hoTFJ|V7xqPt*|Go)O z5T(p>DlNlIbl33MK32$4p`AXDf+%q!$Id#DS9^l%=8WK>nIouX{3~Ujp9Pl;cmVja zBA;+4&p#L^=_W>GEhsEDDu-lPlN>zY(L>+?_kY$Mga{-89`HUD+N$bJ^0+tva?^{A zY-#ttRcK&E@s$+EnBjbO=Ik=kYqV#sS`S$(ea?Ex z_I%VrFz*mxnLVL7qCKKL<$ild#ISV_Wr#eNpfJ6@W zas~<8?wd2XHqaZ_+(1|$?p}_GaYdyjlz;HcBF=%U4?&i*fEol?B(331)EWmWt}Uby z5>8q>5Ux6V)U39n1tjc^sRiZY<8W#sfAPljEYZFk`>0!`IW+1KCyF{hOA}XiFUJBW zzNv13e?*gRsx7uez;wp{fXod4_M?A#(LXQr&vW!c8$a})#}i1sR`}@=*$y+cM}Jm$ zr(SoF?hmYj1ouX*PP5{09Q6k-)16%fI?cJpp1N0j?>Gm1-^y-WCC2kw~@UV$I$e!-6sDZMlW1tgq3pAqcyfOrwav>2$|FG<F3mR5zBiZ*O|?;2l6=OE%fC8-G(EaRPfd;tLpM$Y)Q8rq{Rz$|O^17$++`8q)~* zU<&VM=Yl3=Jyo9!LrfMD@#ItpmfZQtQsD4F^XTPp6uxcavEsR>H+Yvu+ZbyN)Uq6k zbla1A-pK2HJbJWoN=Oyz?%~1dnq=fP`3aq@P2ZCP^2pEsAt|_SYB&xL7k>kCKqG^q z)H^TlB6dS>S4IX2ufJEWX0Y~{QeSeJ2h}}eWt%bsR8x2(gf6;^F5FS?iLBrn?tIS6 z6Nk{cIP2bI6W1CaE(x~;gSOZ+Wm>0#U>c~=LD+W78_9?9-LTbRi@?0>?hK0QRQdy$YX)^qU}uje7s#8%?pbr_I49PODxf~gxn zya{g=84pbZO>~quo`BoAv*jgW{EXIzp{H!D#T{~!Zjk%8i0=eLOe8L(2)z5x#Bqu@ z@8@Gm(aSBJ3r#P7bP}3g?g)&g(ZL4f zS4=-{GWRbYH{B;OXC`~2Sc1L9mchzJ4}fDra@G3tDet78Gn4=gmKA`Vr17HlkHa*9 z&Q~o-?M^{4YZAjCm!#@!evgQbEg3OFxq8hLO)oNI->EZF3zUWNk;aIDiHeuEi;9;> zW6$MPtnruaSWnLa1Ap+MxTQ^E{IfEa+AS9=RLh9!jR8q|q-o2mf;!#GP_C5q3#+@P zg8Rf<_C9ry4v#8{w#ZIB-0K;pC+e}@QKK}+5nxn)5(Q|fjnZCFfk zlq=j6KZSP7GRZC1y!*l+!DHkR$9M1Qr4AMO{^Q$KwNTqK&a4AU;GWOO1^YD{3KRVj za6eO3z!HDX%N2$2??gLyck@$f3mz}amX0^k1{~=FGQ}n<03f)D^0(vt7ZB~wsNku< zN&13oy((%aT7QAytz$^*-e(}o`ND5eKZ-n?D+9e7sLEEE6ItBiyNwV(=I=kN4UY5e z6SNKUxhLR4Oy9_*84l@;fUx$qz$KjAiI+rpB@0|Gbs``fH;Y2hGdMPfDl@&3i9jA6 zLY4Rlgp2tJ9;L;J5iV}?U*4QSLflZD@{I^HY7h>!1AlNolQO$RcJv-_lLdky9N7H z1gCTWiGLZep;}dhzYy_QA>!ea2bGTW;Xd`?qg0$44=sf^dYowC-#koI35>SCB%y5( zj9ox*jcH4|4|nxc__wD zgxEsd@_NtQ!`4p#QW;^Bj;I}Mc8YKV^G`!(y$@AW4 z1wJ5IPjlpzI`Hr7hq(_Jp+J3}O+Hje9=lGDM{!PvvK+q5{q-5G+dA{+cjYg2_@wHj8=dogL*5O_10j>3csU z#KMt9ITNKN$~V)Ibl&JhuU4%jHuTB)aLhVqJtGy>9;@?xDz?n|bzjt2%+F1zTYpy$ z*fB?BDBaT8yGSPJ6}gyZsOt6~p#ozu=h}$b$O$@|IH*x_1-k9r5D1ykl_W$Ve45+R zlN?)Vz$O=U#7(pUlTL7tkrpd#4qGK4B*mIAQgdcqXfMk56^5`{y#x)3OfbMtaxbb=LtA(`aJ#<~tvf!DjX zfH&4VGFbH+?FhFT+P*ITI9#Mhf_Y%sUpokQ=)z4LfIrLz#WC0)LJ@KV-G4Dj=rFxY z97p{`fx-{j4PA0J&vznc^=OPZhapgZJ5*_X#ihS;a-KGr49c zZ)IMJ%`N#-`VI2a_>VG@BPcbc}BD zRAk+*TjETM$2x4n49(!P)PHG7++*GOjN@l?Odj)NlwFDdIZqQZqjQI>%~m3VjXdC- z4f~@eE9T^zm_B;LCkX^nWtiU{3zKQ5Q$AbEbTTqUxhW!&)gEb7tG-qirkFz+Xt-FlC2L zRZf2W7oy3XJ8&MI*l|J=O5Ul{*ttSqbHG?qwlK~b_cu-$Nseggj8$-u2?>p5hBg45o3^*exd5Ug`&|zazo_^1kn)h&$1QIBQEqCviBJc1eaSTK*sWW_gvD%%xe* zVP&Lik|x@ z33M~ajo|_W$z@H~lGaQu=~}xh$d<9HK1d9RE&(X*Kx!3?l}0aE^FMNRg(7!Y7N=ev z3!*@ZL}=1U3ketSr=V}=e?ZE;I5uMiplGdKUHGk8|=L94t{Cfb{Df<(FX3(y*CDCpK zO`($JU$tMArn}ZdLR!@R~5Z^j^&K(%`nwwmf`AcCv|ha z$$w*YP-&?6y~=TEl`hjV-YDB}i7{=}Lqb5VlD?4O_?`1OG&zuJa2$ zQ|kN z9T|B{3thl|74ZeI2VLj`AdlrYFv@i*OopZd8{Rg8awfE9z{ml>AUy1#0v)Ny!ddDF z*Ev*&o5LShIuaVH!z%a4uKzLPa)D9eUO-)HJ#$?nZLX?vtH)THQibcKG|l}+nyy%F z^7c1XQH@Br`PMF+P1Y#p-K2cULw_D-r086ALff?4tabuT2p(7=fzVuu{mEVR9sbi zOe`ef;SoG0PSTCaO16XaRr(^cRX5dBNx+=6cBadT`0NBGV1I+)Qd_bRxjGD7U|G~Z zY}Y!@1r+kNhZQnHgcJ4|g5!zh9)KQ=0xu+6Xn%z8<}sUKlGT;)hexpLuq;^z+esdRz7SA2)um-t>ytS;)^t?fQF#zBx;GZHPY@b zqp?l^TOvk@taYBIs&1E#F7)-~V{$Q_)ycqPnDRWIs1D;T#1JguQB}kV!D!4|wdzKv z5(7SDP~!T6gS0i@*nfsZ>EWz$0ziG=H{-U054%ofn-hL*=fCQWT z>h9V(Buipa@;*DM#Q_^i!jmKJdqzOv+ysJeyk}dI8%5@qmJ?Po5spPKak5smIa)s% zy-b;p`_37mN+yGAvk}2o(oJ$LUQ)qn1b@r`AxE7l-N^oAazfQK}vWr>s2y2ZAMG!He` zO0WWYHN9qy27i3h(8UQmqW;V~1vMWbL^K|AF2oO$;&yz*TW=n|>32Ek`h`Q`qve-| zoLHdhFd31ptBh#iS>#jDQ-6Km1LIl;rzp8LR)RC}Bnmu_D87nE7a$=s z1X(%Lh(cCNiJKP24%hHWxn28en$sbiDR9d=?Gv9ZZ+~YV+xK2F4p{N8le81pj271T z>z4{gJ&;`u!UI)3KU?iU#$tI3x5J}f<7rjySlkv6x@9DxzC{L)c;HjV6vBvXO ze8ef9@P8M$R_W$=#aGz-%-&8CO9RLWAKr@7D{jlsw9ygroAYD)H|9fv+^Pg)^^0uN zj;Z%H@onHi^)~8~i`r@rGfgo6Za?A`y;*MEKdL`STAhDvgh^G(5~;#gAT+%mZRUKE z5pVdI7~$%{PoVGB02c`#MqbxTyi>xZUys82Eq_t~hqu4)E2Zl6=!NMKq+i%I)7)ax z`1|Iv%nL#SNL!Enaj60B>hdE*UoSCd{gV3bq&u9kv3J{<3V8UckA^YFW$)M8?$;iL zjE5fOov(;(0ots!1!E3MU%(0pBWtfZa12%0Re3Ydaz*1{bBMtQBg~-}=DdJ=(i;kg zdVke4n)N>35$ZC_CG@RHp5DQvZii`J>di_`l*rjJqDeS%Be8lGOU}0Iv0L`t zG`Nxq=W{ceLGr$adb^qN)OC%2Kb=l@RHl_vo+WC>;QSH#AKe$E!vX~W?RL-7V``qd zw4Hg$$F*mBq;EUs!bPcx#7K6OKV0LUIDh7v$u>IES3m(Kde|nnfoZZ(Yy!0(GvHOK zjOeyi#Ud^^;hArU5Sp~ry)vC$ZSjtrld%Tyoqqs!G28U|hv`$T>P84+`o1nDdKff) zYkD-Sp-0Hlvcn0rHx>ddaHWw&;v*k_HVAz1fOncIi9rv0WX5l0jAydW#Veg2r_bUqj+iKUA?PS!rS^xFhLp;4cKUfC zK%WaP7DC?Ryq6?Fs%OAZ5#Q+u+k>`wwEBNj{E}`v(57wK!^tddVnZDB)uANf94vEj zEzh+`x49FWQP%OI5fH6Co(2pEX?`7YvADi9d*56Q58dPFl$01(FAGO3x-9XmR)iio zX@e39==Xi_ zl29^~G8R&4ci1*0*P3G*yuCxIWF>FuE_)vjNCKlj7{>1KoWogd7(uc%ykP~bM?(&Q(xvetNGX!P;mC=h_Tjk0lB6gt0rX?3NZXJKt!t*xF zw^=_S@pJ;?Zf>%eOPUQsMiGRu-(4F(iD`P3`bJTZ<^pUuAcne2CNR*g>h!nUh+*y5 zrc#62SQL@(R0c+~UqqQL&|j?VUWnV}Z+@hbCuoQ9KSEn~ozbb2b;vcVYdm5zY(yBj z%xhn9#Rc>&CdXeWjl8c#m03B zfSSt59aPt2h1X^;@k&0er}6D|SY9p)9;3iZP(-cXcoBm{(vm(aalC(le6$^iR3yy~Fhr94G!q7nQDU*4kSmMw1C@mVTd3K|H~tV}H9r_*r-l9Y z=|x%Sfik$v^nz}ur(WFMKCpV=)S(A#dXf(+lb5X|V{?Bsz#)D<&Vp-neYC}}N)C62 zOX}%MGdR?(Hf7=Px{!A;hyFB3&`sobh$Cgr&E&e6{xA}*EA=uCS>o<3Vi>Ql(83A>a+t5E?N#=KW@dNPn{Tgc+kCNLohk9Y0 z6~xle1HgX_ZD6{(8rpx`M+X z=!cUY3fqsqKqEC1USw2L8~gsm&INLcvnsUcA+*UTXRk}4*uAV3sqkOTMx6HIg1{+C zdV3pGvu#veAg~J+!^lY8n}d-hSwv_m^e(!CW11liTY~7(k!S@uXLk7NWgq{f*|Zob z`DuTpMCGMz3>c+=hyE@B zEr!#wIdpHcQ-WP@$p7lynD#wd$2JCuo=@u}hU4LYF@n(TE&mm`paR0`G3%ANYGCMd>CotNZY@&R%)0REX9AxvEc$Lcxfr;xi~<2Ro=04-pJTRU=Jn0Q;Wu zgki_Q-rkU9RX`<0URx!pjW3rYFjmXiRa693je>pnHi4(vtxC2`hTlxHgC^YI#e$Ui z6$<_ZWJDGS98e(3^;_GuSF|1Ku z`yjujDR=hRRT)9Zm@w@8pbH}&+1lL|{&tG|BVe7fy7r3pPe7O&=9@7P^$=x$qc@4u z;nMjMm#)^$7yxVh2F>2E8_C}(-TKBE8?QSg>O76#m~h^@dIO6d_>!OC<92@#LK)rS z_=P-~3)CH0NF72&r^%D|4p1@AT*5yy;?tmpo3po6Ye)d?0hI!H##>!^O?=s&Q7Fd^ zR8joesW%Jfisi9OsWIvzqkQoup+;9Q8dnkUFqR`Ecu7TRu zt6#rrMygr(%r7rm+_LR{R!_Vft01SV(4mr1e2hB|D~loxTbMGy!NJLY<`p^BD1aZM zOb;Q%iw9V_~-K81d~5pNc6 zjMpfL0qBF)TvpFw?E^hji$?48a2yDAs#_a-|Ez5NFje(w3OQuBzwG*`_@V2y1G1*G z41{7>fF=bGFSI@SsTY6B{7Qk575m6<$~RC7TiD_L;!bk%fPb?Jf2W99fq^CV_B;@M z&b%Az{BE-F=Mwge#hk9&$Bmf9YjH>8;Fe;19iQbuW9{t$aBINqf}u)0nNrK+0nN*R z7Q(-8`f;j?<zjn zk^U*=;%7Jdmhyjw)kV-ZbpcgnMHiH&oZQyWB7eZkoY<~ds`6B%I)|d#8HsFUrLcx0 zRGebV8xCH%45xRj)fP|lM|Cmc4$QGz00EQyIz$>90?eB{xCqWzYNQeojB$der)^$= zddRp7;fv0F)6GL3A=#pEXcWdCBF;zg%db{G0{BQ|^bUXQRS&1$&<~F1n1W?a_!hVl zD^$0FxjdrCQms2Ze(ao}t*xD7v6-GwuC8*d7EJUB@9CGIB}C-3YT)1~-6AQlT>NlE zz*r&;(2dPOE7tTUE$k_F?_nHe%a+IfH67_0Y2aRUi=S6V6reiU9|?EuuS9LeUPOjz zh^ja_4P}2dZNvmn6Lmf%uM1B!sSw5q%)78R;#7&wek&8RX&ST{%Xy>!`V9Kmp0LSJ z8Ig4F;fddUi)@iOuhQnJ2X;8{sz<)fj_^J2wYWAn?*f5UWLx#9PJ`>DJUN?TtrCu| zH_1|43-WyYI7)xtH?bZwgp-+r1y}?qTdQ_K&AbK4 z)K-nLwg-(XRMWbwwD3qbuklOkr9QL``%ZXu`@t!xY+PiPGnuK&mbxS*33rjuj9l@CA9{e5DFRJ80*k_<^^;(9^qJOC z|6H{g8L2919q>HC!0fTdlf+NoP}aI1DQktGa?bIKHzTRcsGt%M4jmtd{+6fmt!}4R ztNUxx$~zZ`I$W9Xyhe{CqAlXERbS9))60_Jf3)^?>PM0# z^mhzjk!Vr~nVx4ipgb1UprnvV#UPd^WcPJv@^9S2ks2K&m_{V!N}kz&B}7aUhIg#krd<9PK?OKgXIlup4}BOVj3R zO3l1-^@d|Y;pK}OtL`t;y#JwjIwbXG%o@eZ8W*NoWa6Yb;QM*hy2MJ69>st5s_KI? zmQ(m1QzCI8)-1hnpQCz$4{uxW(0a7GyXV=%OO><-sMX$9^2Y4cDPr_rvz$s5uz%@nE4d*a%my)I zByZaq^J8D?#VZCq@@xflJ0p4>Yw;A2h+MBDe$%#bqu`BE!sXA@nnA2?y$TnQ`44q` zc5BQv-g?3zX7!I1$w;l>;5p0ZtZcAh1u2%J3a1rzGFUq9rid3>7g2u-wklGx+wBw! ziVrgnHP<^;KVyo?$iFGl6twYj>m#2;o#H|$ZF20}N9fVx<5u(A9RO8)mJ-Sl7N&p=%yIrbA!bLDVXkKxPX+C!yDUCtIF5sv zzUo-4pK;v`DPtqO0;PWg4!}Hi>=7h4#ZMIP=@6LxpzfJ~|1SdV_=e`bhJ%h(_5rQq zG9&c}p+~KeWWj*h?;mnFeaq9|Hu{`GZHZ3N(&(wVRsMY`F;sEH!0ZqosdhGse0UfMcMowQ9Ft zOn#x{$9B_(%S5fbU55ZpSZ=)0JFF?Pvzn_GX8Nmf$l)m2$1$H3+_Pt=#_bmp?XzFD zL%$KR3$5lGe+K%HZhk^Xkp3Y=e3!!Hw3152GS1ZYwV|H&0SHJyl$e<5EQz5#n*b^o z$ZPoW*%-~DA})WGiAb!oaVWyIT$ZLc9&lz1u61Iqil6EH$yx;*Ob0N)g4_&35d<~% zfB@;x)B2>(p4p4gqP5NSw{cd<*DLcdA&LK!J-dVV@SnOrR@;_w2K9s+VC?FA(qY73 zPSo8w;ZzEgAq^0qckWHXdj?yl$Uri>S%BXNXGUT02cv(2=Cbf0?%;zP1XV#BDJ5L$ z8q|LtE=rsKOdkW6_j(Eyxj0jw2t${N3z81vF$ZeI^Dg;9N1S*wEL(LhpgJZiwQakw zYh$ilXJ-y2xwVZC5lh~sK_SDzSv-Bd=(g&RL%8uEd?x%dI4*y`KKh0Ng7ZF~x8>vu zIo@b@Wgvg8_83BIsEVc3LaJpcW^}`OOfCtWmz+Y_&$u3Wtz`6rI3PFi0x|%waMuDT z%FFL!+L%Ct>}H`NwwpJhkrCFI103XUfZMD$6D5cgZcG*=CeeYgqcS`(NE^uT>0Rcj zs|pR}0u1%N=?Nwi5>@VNy$|!oh&@gWl7N7F9hHB)cGL*x%#kKq$9A{+3=>wrTU@0;M(YyuapA+avU z=f%xPiwNshnDgA3=_;PqzSQ_?AZ$L`iw2y*M^t=yIsEPJISFyD|Bc`?AbJw0ub;eV zt|EU}r?ZQNV?|gS5s+7w^_7pn8s=RJxu(g6)Ju^5RUYCoMXJL$dt0p~p_6pgDV`BJ zEtR~lw5%L>Ff@3ks0*L(dMD3hGggqbr8LE4JbA;i_wAh@*xN(W4IZi(;vCKnO{tL7 zo1fX?ZU5wr{r~(wL#2ytreu6B^IVb>mJ5ID4_thH8*^#aK;PRAP!ZGHj$k<)a4xjx zCBbMYf%0iy7L107V6;6e3tl=W`slN>z!(0qtdVsL4B=jl%U)cF9M4>JEDLZ2Z%(#T z<>7u*2PK$8>q1;7qL)7=r6byhfD{Lv2KN7DiM?5!7$xi7SP%+>XpZxARYSPTBPT20>F;aQ6U zl^FIZ0C1iR5vh=0wM0TkSI>|?-QMoydiFH{F!62yV8e+Lq?0xm>pMa`*xhdQ2SU3p zkPiIWil@{qPZDfN1!NW#@8YjkWB7lW@&h^*wqD#bc#aG0ODZI<$mGGV@s+63?M#^2 zLI09V8SS545^wV*=!Iv!%7O$r#4JQv5^-e@NzC88NB_*&8N`OOQr z*_|UviP|J3KA*XdH#bzR?reY5fm2f4wMNd+J#u`2K1u?)s5>YQmsecKE9xlwt+^Nc z)PHIewIk=dpT9wB1Ty@V*Y8E>l0pdfZDNqx=rU9C%8dp5eF2Io+;S9_WsRicA$RX7 zInaGcXKKl3Is<%Eme9Ai@o*uZ#rp6YJw)#4$OTT-$6#=PzCDnf!AO6WT>U=@DHm8g zoF&tiY2>UA-qM}-M9*LFbaSuZxgs^!mbfUq3>%=V9(fgW+w z!M*!G>;m806Ih>b-y46*slCHd&$qLRNb5E9`8WLs|B~Uc&&ZJ*Dt_7KNgxUH$=>wi zZQFzm72eTW+V^q)WaaZod3|Ry6}E4=)0>CyN(3*GB4kv$9bqXfs&5LD=g>4@EZ@Ca zsfWLjL%nmVw*_>7Z!CfdtHsXu+?vfMa%Da*!2~{0aLaRA^Z0)j%0ph@0ZCE$C^Cl# z`Z@=M1i&tFc`NBGac5mTG}JFQ3LLu}j=j7Iq1unP6`ft;w)6LIJE&y%H-C8}zs$$` zf}0bfsBolQ-bEd`mK#))RPdZ^Z+n=)Y}zW6j0xwRe0MT*#|#x0tLQI* z6zv3T=V%~ec?&?;vD$k-L5Uy;?kjkxoee+{A>?qnd3vp$$beEzLQKY|O++p;KKFVWcuL2g=S- zY?)|~n#Y4oUIw8X-Be7u5wB^?$HfY8@`)mpYDFQzhNzhG3S7F{TIvN|If+YUid#m4TzSb|ll%s_vEp0_NqebhB1;bXapzHbZJJhdqI z`^PG*Vso9mTosWty2_9PqtezqZ&in{BKIVWl#bzV()aO$o$c7^`Ahv7wX%zZl4M6u&_ugtD}jy{B|uB0fFTaperr|Rhtu*+pY zV3>bmKL0be$qbc}(okG`ufp&?RA=cny07;te}+F@3dJ+*ZThu9Tx+GKl3zPJk=wL~ z0<_RHg~hn!>Hu1V(Zb2)xmv5g2KZZh4f<@xe-t*UsuYtgamASBip$Z>8@Nc;V>#6+ zxie8~(qdBCCyU_?S^l-zCD&UB`c8nqEmD6}oFewd8;#R_jESCujleRonaq=|Xk6N*e9%impk+Ydz-q zI=jtG!#A(%gb%pwf^WGZ$b&RDYgH}A#Y0vJ*z$P^Gthg_N!Yv@&_a|G9xEgO5kh}% zV30GCiNJ%LtB9FRrhZWpN&s5YW`BhKRlv7B`qdRLCj#hR2eo!s@Fl2O{mPOG6E*lQ zy*cjULMv#^`0p&ysua99MOzp|u*#0IW-l7Pqp{(X%ZCg*IGpAgMfL6Mf(0FE3)VxP zOKc}RKKN!*^Q2C%6DnqQ@-9x2;aY#orx_5RIsM(uV|i)Br zn|V0vnP@U#zcx8$+omdQ5L4wwpPiBVyWf6Q;Z`Hv_}R;plh4)>+NLW-bGE6;gCvIC z-l4IC-~WMS>WgGgI93}DnGSP=>_G$CKHzVk-8ND@SuJ=*q`MEip%<*vbWVS`cu>zt z9B+jd4@(b8S@_#U{2L2ojcej-SL`HgAJJB)wiJ>15JB#{`8>q`9@#!l0X~+?rfU2+ zM^HNE(y4IQG zQCsq&h9bcnYaED}XCN6T6(oNILJYRqP0+fBt<|YZ3&RE2v@s}obpjfDhmRJ^OtAYH zpSPo`_rbYb<>ZhqesYeg4o-&F;V194%`YT9GS%LqB2Rb@6|X&(ceEoG`on##dg8FJ zBF^8bAYY&pV+42NPF3Z{LYhZ7Fe z?pgGZxeZ(m!EEk?bLKv-A%T1&;;Q_k{)JLCWO4lBD>4O9i?9^Vvb@dLDGy6NFI5Bl zqjN?DEITVZ<-BK7)Lnmw*Hu9{w($aO4oie9QV0*KfRk^T_hG2bPo%C65M!(FPO zoe~oHrDt}Leh`Xghz$3Bql81lL29}y_~YR;^LvifdBG;!nrBx>+cl?i{DZaC;8|S5 z?rI^u8YbLEO$vWJ!W9L$Am|Xwqp{!^NeWh8NtunP_sw{-jp5C1O*5QZxmSyf(RDZ# zrZ`VanHB1_XKKY-{YbKYBCF0I%nkW(;$^`P60l*%;VKwykMx*UX57GQz=K|WXSNy5 ziNW&Gp@0v{TsWcA%W>9lBeL!c`);%cMBd8_U<-uWTg`vGAkAW*$NiQwk#wVc@vh|tt83Aa2g0n)0x-*X3^$=1o12XX@LiiPh8h)O_ziAY6&(yPBBqw;M<*O!rn1ARfCfmo@Cw1+??G{Rrvq zf+(>Y(TjgNBx1b8beCni4?!dSu52%zG2M)+Wu}g%dxxuQnC|`>HdmE12;(mt2D1x? zJDTzdQht6n=LdB!OPJIr9gHwXRSbzYb5rNUQnZW8nk#^pTB@K~f{j4P-YfoynxH{i z@gRlkcwG|`3U1qxYPM1HcdOv|*(x}tSHW_BZ54lvi&s{`{FGb;wJ%q}5WBt|WN8`r zY@s*2Syp~5BIMjYz@ODwK;@e1ff*U+b|!?bMT`IiIGVq^V?Vh6|hL`!o}|bqk|4)d%cde(mP_B z5Eq!XFC_O?wsPj`Rvt~RZ{=EgE0@hyF3DCdf3lTNpKayvP|>4}haAg;PIQ+&XJX^- zD>_Pw;IP@VH{(<&i`ePHaog{GsQ_p12~L0V-h2xkkzHoXJ7A@vVdyO{b;*PSbx7|7 zB(e5c{>F(N?r@{vGY*iATW2^5i~CX%7Y7LRj_8XJE&RSO6X{Df-51v2B!z+V4P3V5 zY41dj_Pq)oP4#W9*I>@M&UDgteolZ8!G44L^`3L1dl|N$^pEwCJ}>)k$o8DVySaaq z4!K_`Tau_UQTrN{K)Q9&*9SO40RsJF>m)v$&RqF}5{sWqVE;@<@Jj#iB9splvBwVc zezxk1w~M8$RMVd2Zy|tpf^04}D{Zg#1oOlNS+a-!Eno zm)nHdiF;X7;s17HERRD5Ids`_(uZn2mnC)i5u?;Lp8IYzYLaP$b6H0z$0vVu%%6(g z6=kBqZY<$I@|S!25Bh!7vqPE(RHrH8>$tsL3&jg-;1ZY zaEQqI)P}k8E&0Y?{L?pHb0!l?vC8ki=2BN=c-H?*hR2fyeVfbhyba<3+cF3vn4H1^ zTl~#{>4E9S7q>A0fZXOhB~E{>takzZ;vx@i3%2?}0VZ)(*8AC*OXH>hA9AJ_04KV4 zi9M)6yxfuB+H(n}Y@knc$9s+3y%OtHchfO@3bJ&rwyAS>UJgkx{anCZ>*T=^%bz)S zVFc-40+$|t&&ARcILCJ|f4eh0>iOhA|DdX7IxXsJmAdY<1I{}$26%t#Dd(6T)fm7{ z{Zp+0FpD$BhQHv-tcsuN2Yt_}c6I;De#|d^&+S+Wyp;I&LA7@Mb}F#!S~`DQhO1y1 z^{@hh=Y^{7<1c(x64E0@-!qfh;qOMOumjv+;afdDe(dQU&Xk4P?RE48^>p1%b#yNY ztLukvjbv$_l~H- zTC1G8NbSsF7tPcXvgDY|q@7l=;E;b}2qy9gTIL=6!Ef~qa4UamrDUvbjtEkRL4G{9RR$rYXKtRA5wOMJ z&@chy0Xe>ZLWh5v;p>B%<3FAJNXjRr76}y%jFXYKOHjK{s*3(V!UJNbZdU=o+^*rT ze68wWpz74{m%nzh=;upTew3org8FRS*{i7ohh4VM1dzb`Kt;1Xc6#NE&7&D$ffXTfHRVKHL24Cjl z`jEoUQ%rv`lU0Wi7oNQ#z8Q=dxw9j=ScBt;HNQS5U*zrd*Ur;QYAC4I(}y->IY{~! zXU)9a5KR+H#HEt&4j`mGn};sWlfm;8*i8!j~Htw53G0v~c|$8ya%1N^T$0lcC! zWo$Q%L={&4bq>p=7qi2obQKZai8`A#XmsDX_>F%go#`J6C9EA+K&>YP-ap_!FU2*HM12w&56fYniR&c>uc8IK%DAs?lCBW z3!;DPP;4hCZEWp=X2j6z%~8_a+otM@y1>u`4P~GT)xcihO|a}8?xu4aEcLvU6$qr9Tq6+^r@Rux2)k+L-fnyKL} zJgAhC9BgB>-+J_`QBc>zo9Nek{Of`X;Myb)7(ybiqU;2*tj(oHf6TlYpCT%XM$r{U zKdUAlRg4}b+R^zOJ;BMV6{?oo~HP+#9H)W;805#&_;_vUY8xzc*LoyiP52Mk1c+*-oWf^(=RLlQyiJpOl9~ zQ_+LUpoT2|wq@O2`8I61yH`2e$hJP0w6nxZeVI#qBnF{mLj(wOW4;&xWxanh9LJwo z4h}gzef`t4!jFHmTxM?%PY=+54i!>WyX$-`S1Ii}>3--$$@?XyaA3q|%im+CZ;Bun zS%5@mf}{IIhgZH-ZDgOOT`XuD$J@A;8FMscJ9M1G+6VQO{B@8W?>-UKJU;;F@XS6 z=!`Fo(HVwqq2`%J)HuVYq2?J`0N*;Ur#6yGDEIDdL~HZ4q}H3O&Ln^R6GbXLN;Bgm z+kDc66dr{azthh0r-P3&p%qG}oydN3F<~*s(rJI;rILfA9ZM-jwOM+p6|oYS8&+)B zFznogfeU5FBh|*XOcmc2zR1=_T(NN>o*x|-oKEck2q1iowOO(dU_)EJPfG4K#Z7l2 zx}(7$PL-JeVVf_jjr4z8@;TttmAQF67HbUk7QLcTQt5QgvqC*hgza~mTT{pwrER~& z|0S__FW?B_0t*#K1cl%|V=QbZ8GBA9{@oQN?z-*7(Z>y2t}W=^t+Aw|1(->(e*?~M z?Mx69Z=r$_<~y!4w@+~UTuratKQs6DqWh=m`)B6<`L+8O=6-)hH9R7k+pY)9AS&b- zWae>NlZ9#?w)xl@&4+CpsbL!Id!i=$Mf^3rSTJ6mUc*K_v*G1iab9`dBw{bL)ifbE zN%3F(h&kM0?%yD zDWg)g3}N*j*b;vmxTyLUGN_dlK}Q{nAm{0?Pc@fMHQTEJ$;b%iY8H9?70@8^=bpT8 zLUh(0Ba(62I6r}WCBTL&akLm1-BLCdO9Reg;syEjxz}fE<16Q0$J{8xGjjuMJao03 zI0wU3P;C4c$KjAn#D3h_=#rp~_^9X( zJu5Zip6Q1fXx%R!b1BkuoIe|GV3}hH3SisUFGC3a=svr0t_$CmiqWjG0L|6!K3=4UdWUigqxS+&e}$2!AF2W!G{Z%3yRcqhgKZ zLO6%^6>)lZkQ3?@)i8T86nmJD)YC3)l!ud&MlVAX`lq-Q3`j2lX#AI5#b->ht^ z(b?Mvwf=$Y{qPu3J4vcvBk{BZ+LzuwgX1W8lDrn8$J8_Qt-ptBI=Z?rgy((^e!`x` zYudKb=mz>>A^go?UR_p68tb|m9Z~u;Ji>XifDfH7Xj9RqxgfJ-NUA=n7KrYYS*EhW zFf@OwJJA1Ol5~T;1B%>v9rw=)E-nxdyr7`v0wHn>#z@{61M_NvJgP2b`?e%&E3n5h zWQ96FD^E~CyXWw4xSE{E!puOAqJD;kZOIt6)9454Acd=pVVn4+KpWjDI;Lm;=f8S~ z#F+U4w{B#TA31js;lYiynUrh>#T~{Zv(eFymKh9*yh4jO(lUVSM0W zU6^5we*g^CK?UHV@aKER8Cl=V0E{4CxWCMcnm(m}4~^c3*w36p=0x;cDL^HP;Y_gn z6VRIE^>50~W%KFrx!J4B3s~JrU)2iq9)TLrZ~4sYk>`KfjX+KhMM%^f1M7yPvlUT$!r!igNNZ8P&f)K~ z)G}BSX>v^wG*`$=f6FVR%nYkS)x4n3Eskd1&S0576o9FHF9rjAJiRg$=2j-xNZcyt z0xMu6Roh9@3$P4c(Lxq?L`TI8 z()_l$7V_3QWgE#Jb}PVl?h1P>-p4@-3)cN;FUl1!Iusc^FZYhoxUAL!`dso$op;T* zbU)2>{td+ox$SLqb)S*~Gt9~JO5aBdmofGcW+6k;JQ01)QB+ z1_L_OxC+JHMvXd#y-UdYJfXvF#J@f-Gcjbq(U$1{N#&7=acU$}cjlOu_F|t(-8o9w zF(vFubK|kb z1V{ZT0}T?yy_sp+#eTfpmu9)Q5_|Z7N`|8X8I@W1Ghj9M=2I^A50u%$J2|WNBO+^X z*QzvfO|m$w&Sn`<*#FGv*t>=0_YzvtK=Qf*N9e|=f{}kiKK+Gv9ggs~*8z?Yzxmc+ zbO*kZ-aiMMu@f1moYk_>P_5XOej|Z#R=K=^5F_Bik=lAFGrUAsaw8a|0(i4N0413# z_IlyVN?^C>`UI;8*A0@%HIlbYAc~`~5gzJ(5^su|d57UEVc)z@3qOf9y z%+#?kN@Qm@=>nM_L!8PWNRHZR)g_maiEi|8n}C0{9YPuLCz4Q+pWFhG5yd7<0kQP)qnXm`@2Y;f#z{jyDF&e~)Y=hQgx$~@_KzdnaBXnEK zg(ePHb6GlDncNC!l_x2dI;*#sA9r1ZOF4&7S_g@BoX0O%-l2hM%gDF+z&R=?nhO-Tz{SFRL86b|}G>=>Dp`l2gDj4Y@EC;E+bweET@AL&Lf@ne^A+3tU15!`0X zU_psYTuHyRxKfVe9K$#(;8(oJ&ojg_3w)P`+T1BZviHWQ(shEZK!}}Ywg9H%h(V#a zpMU(TB{+oAHkdn+Lf1NuZ=x=cKk6@=7JcxU^T}J=drte!BWBq?);UIbKc1w^YU;3~ z;*8-I)xz!OcC6zsMjn){a6x}LPdZk-$f+7>{NGW$Fm%0S-XlxWi%8=VDpe-SGcY$; z&)bnF1@t7pjt3Rx&H_tlf`rgiqAo4K5yfBAo=cPi>o@DApRVsZy}+!O}|A)&pb#T zJu{pE(zt;h%hdj6!0l)Z!dG?v-H0C5*}gU?CU+v)Z!dzmi!u_~%{oFSpl$L*I7hH_ z;4Ok9JSfC+PKQq!cSnEytjW)L{9MD&OZj( zQX_!Dbg0q=S;ZD+Zz`oPvuX0NG&WOlRWO0-+Y-@BGXIL&4&3 ztgSre)|!6}fh{@5-+}NqEJC?PgN)^bR6$U`KNky3{T`^Z0F-<-yyFMs)Fz?{4~anG zZyaY_pu{il8MJd9;3;*MUxQ`k1_blRg>&sGo~b1J>M27U--ZjCv$g9t^~SXZBbN2= zG&mo7QK`n%JrA!AgrN-oR*OVPD=_oA?v6(KU-y3zs;YF6!opV?6nd=hHMsVTnyi=Z z{(6IkOZ{67jv5ARUgzPS+Pz`@d16BBG#~5ZoB%J`jfd_3%$c=pO9IMigJy-Rp6Smit1WLE zsA;ypt1)dJ*QaTViZF=VNK*=y;m_+vALD<9F}+?3UpmgPX0ZJ@!mIIEa-0`u!kjj= z!#A(ZWNFsuK&`!FhtF(A&t~j~gUzLXyx@N~0u%bz-NpUXH{YV_%6Z6ewPX&R3@CT-lRaPo*84pEc6I(CFF z0SC}$1fYGBS3QfGTzFW-P5q2z?WcN{%DDsYbbQ}{ES$-?8Eh9mEO=qFpq z!ML09p$wE57P`7o%Q6A^gkNLs_>AR7?~7XDIJ@GzY8#70aG#K_*( zRPxaol-B!Id3Y^6&l3;N%yr`KqrJRGek98SwYmo)nB02`$C%Xk4DNqj-6t2VJ?|%< zyXXu3E^aN%Q}2vlQ%lkA(bmezUV4PLJtGee|0ed*W8%3}XZnU5TCAtSGZs`uUN@8s zi3L@7PTab5#twI?#`l)xp@BS<@TqpnRPUx9x^;>#$=;S;AjRa)%_!B~(o3qp-Q);A zKxW8|g-mLIA5!BR^!a}b=E9eycyQ@x$@LlHo2Y?FuPec%W*g+aE}W^tRnGd-dwG-M zHRoL0r@WAyZwfc@mD>VtpM`h4nDh>>3K#2H77p@PCnXnBSNuo;Yo4@#`17C0116 z#2K-SEib&+o2{UVhhzITJ@dKzv&6vyxnjwno2Uv}JOj+~7mv*eyngd%aAV@PA~A*< z+{eO`fh?CIuycRj6oJ{2B3S;lQbUd@gs;99s-Q7fMhHFq0SfP6F27bnC7G1dy{fL_ zZ$wFBN)&;gjp=+zy~x4SFy%7jvl7mt=jHM?$-=v-$kBd8YFdjL)^)wW!!Iu%Rt08N z3Yl8abUTEkVU`k==YiIa4V7)&LW>eDYT(WA55y?1Z!>?0JxtU-bzMNb(fbt4(fq0I13^ey zm*30k)R*94`gN3PUS=u0g3)=wKxCuyp6NW{`1gg~Q7CAe{5IfRs?U{dCmx^&;p!GD z=1-~6_i%p(*47fm$qS)(xDUhd*^LrmY{I`ExSUPHv{COH!hScLm_zM zn%J#k1W2oMd|*S5yf4YYaubKh+h}0m7d2Sy>U_niy*b zDds;D=*$@m`lB-Y&&=~~bHhyC38JR;L_*mGEx9RHi%@y`W(mEmGpQvcNzaFkoMXpT zTJ(Vr#B?aH&wX~()V5+FXi2#u!%iV)kWV+UgGJkaVNrI3sIOliNnaX6^*-}>rAM() zf*+@xencVL1j7uEWvD_^7l$|xX|M54<_w`O!I31_=J6*9ys4`Fy!!rp$R1{_GtiOY z$b5}33==%#CHp41W}YD+Gp}|z-+_*lp>}q|Rdo%15|c_l&)|n2ET>IWM)7cEIUwc! z2wT2?u`+91Qcd@C$#W2>;YKi@>K}fmMPDkBr!AbT$>Ucesgbl1LEa6Sk?Upt$lje1 zyT9Dbo2;uCD0jb3scZg}2j)k-K#wPc68UWp;RjmUD-|{ss;@+DLXXTo^XM)xx)ZhJ zOagQEXW%jrGUq`y{RW2((yR1Q^qxdl=m;EtBK_pcRl3*b%!l`&oHNsAO;*o6Vw3QI z_@`$U=$K*ID65?WsZZiN;#b%s(ZdU7I;oX*x5&&u+L(u{MCAgiH5M4@6W4FG+7)!B zUp*o!&Lc|hGVMmaPu$`d=Juxf$FVmc5A7W}yGQ@nA6Or>CQKfpnL&ywV>4-SM1|OY z;Q{AJ@2d+xNf(%z2^Ey)QSby{qD84i0Ak|Kyl!V+YKZ6WOiEb?RZM@8yN!62DZ)oX zLmlxVBwS7c=tf7?21nJ;)43s>((rq-nx6gqa3y|3I@AK8pp^UDbWexYDBP&`L*xpC z<~2Qrne5HBg#j|a|LI*yYu0rf76KlBdDR+Lm2upWeB?=XcJB=2j^YO4;Mxn8bQOr& zl=n$L6YB>%Ajf{vaOzaS=h2q0uborOCIc=Qf5^>{;zNx&iP3azqrJ@KURerTHC*0) zxe8o~Z)fZ29dj(j4H+2d7J5K+pz*UEJ5z7+7CM`=n0ZSzN^n-lJ^E3^8kItSOvm8A z&G>7l$x~=aRWDwfetHfku$*JV=Bbq9*DqiKVFw8!70eTJq!Lf#5{u%5NTd`6pD%`h z^si^aHx-SxR)@^hq=<3q`;BGpISDn<{28e+6-7dPn@?*jq(+mhabPwrkV@Ri?~pE( znL=;N;dt!MF;YOl@ykUAiC_SK0EMGomgrKdz}fF`P*t(3!&Bgyk)vJX{Hm&Lw)tVA z-{??^Mk*U%OIIkD(W*#m+Z-t{|>Grwa$hs|w( zF(VW*tpnJ6C>cE=%?V$HbK3c$E^hxt?=c`j;t>f|UaT}JOk>Oz_j6r;d#Of96m27C z0-L8dZ=(vG^n^W#Av&>TPQv1uYRDl;22*7lMwEbPNYAINL$wy$TYw;->+FDU z8lA!%N{1d?3hyFQ&3FPP<$J29Z=X04^UR>6f@H(G$U)7I6q3eHzOfdM@K0n-E9-1Z z>~v=jSaexg_8+g5j<;5SkFwqQ%5YJWQjq~-jpTI?jC}mOHF|EBWV!JXU4I~3rp99= zj-GZlAU$8-lGDOGvMWV-*kjOyK3ibutRIk^Xijj%+%H+#xi`~fp0yGkJ15)(bke=i zf-*;)k=x+_h8oH*^TuYHF5v7^u**-NZHlJJResNW3KD!EE6YGeFVmve>K=ddxrvRejD9ca&!8} zG}lNfXO$%zAL%=kN?jma z30bzvA9SN?Ruy*#4u}33koju_13g?5S_8Sd7o{P1;>mP{Tsu-*unC%GcT(Xr(5Fzo6H?pS|)FnMQW2iwcsjiJ}kw-*hR zCEaCW>KU9k!JWC|^D5SVYgwqw5lbd3pB`yZjTMIT2R{=<{0Lr*gbjYk&<&w&S3av` ztfZ5FU!$;jxP-k`J}2gx6hC^w(Mk5N1SLoh?T}E>P2QW|tvGggC$*6J3qwE+2KLv;qBsWYZz z4_(#=B=mDsL?4j8)5;_2*vXv)(Htl6phP-hNA$K%0|0r1xmQzsYeugf1X5`K5LHcp1PGjN8q3z-Pt!=x5v04M@0xK+$FV;jtW zfNkV>E<&l$r6ZDV8aavWI&@^Kv#)XunC9*Vj*)H^EiP3qi_+0Kdk6Gm`hrkxSxLEd z*|=F_7Zt~q$~yMrK8YfD1`*ZiQJgQ)8_#)H^tRn7!9S1p4RBzNL9n|4kHn1c>>4L~NTG0$@Iv75#oskB9p zEXyj4)TCN@lc@ihz$SDhCLBaiEzS3l*U=Y9O4Xr@Ts42 zH=BW9k8na{#zMBu2I9HqB@D!r_w8VtbR^3g>PxMcu~QEw^_)RGv4^KfHY|d7Bfs;n zdDttQdf2bhV*X(rg~O7I@1Cz(n&gqDA*EChL~~kokS$FbjA`hsFO8lx-nTaMqlLy? zdu0&_GhVJQMTz0&aoW+OmDP-Y5el?55B!u9s`?A=b@RPZ?DycqI`S#LRCq+>4odoV zTq%AzE9ywJg;%gk=Wvq4Fuh_^P@(P>n*t~oAG~lmMG0(`0j0z^@H*I=b;2%otrpo7 zw_dbo!}Z-XTb61SW=uX*1b@p>$?Pm)&DYb`JQ40N9`V!rH$x5*88R+l*o>A*9zA?<-`{fo{!rY4^1nPU%xY4x+rW+ma*%-^_yjTE7j6-byCIXmHHY)@VRk?Q z?0L>Q@csEMWn!IwMf8S$E;6IumT>5Gr19RC@n3b>z6f)S%cg=noZEM{SFCu;XP=T= z{_p}DW14n@Kw4Y+B%cC1#)3xCxR%)^gzvIpz`wGyDS{s zY<}5%YIv6U@zQ8t*l9bWcIG$eZ;CPHuqch?i6gLG(0;azh^C)lkCVYq!KnCCqMl_5 zV?5=va3mMvo~T)WJBgRxjGTBC2|yBeu$Wj%ErTM1ZZC2ux1Hn|xaNKbukpE}6TXpC zB~qsX+s*?~!pgxLJW&%)^V6ctd&|&bM`i~SKxb-R^w?z3xH4R^4|2t+9fdeM*3g#K zu~C%Yw zt@f10eCHb(|6u@64_hX^vpC`N$0M#mw?Ph_&pcHRk;{iF(!cUk;Yy}{bC32=ilLbSUjNLE!3{myru}Ug`2G^R zs^vsCb!a`F#)2S>gv4kxaz#Pjkz(AmBZkVtc_4`I+ZySzU|iPlx37~)rP-wmYIh`3 z?u$ZyAjmt%>Qs&ANhD<*YR%bAoapHLi=BFtb=4Cal9i}FTzKnd>V1s2ry__;!eCbf z`^bouX`f32z%6Qf;&mj_o)1R!vj*`5JBjXN* zw-@%VH=8(#{Ga*6VRGW&#D#M2ivpeHjy1=BLB(=~LXIYX&79H&h8PXoJb>ru*}xo9 zrI|8!kH7dB$ql*v_(Xq7TKv;Q-fN~3f6!UD z>^nIeVBuI-l-|yiz22uPH)n_DMbYJ4<_9&9Gl1e)CzQBM)H%nUwsJyvu|d8BRt+nE zpP{id0S;y+&!4*^_Fw78MTOLNd6aKwh=9T%F z1?E4i6c5l3sLoD5?hMmycyd4OS5OrWE7pWDq^NtA1j+JF0I-A?dBp6+SPSiijq%#? zFyW3)`Ibu!@)Ivwtyi!?zMAlnU z4m9PrDN?fMQ?CFG7hyYy;w8-GbsH+5SYp6^5zyEbMyA8)rNqkDp^Zj)&0$x6?TSdw zN#p_o{1SSW)v3Uz?UEYKVZ|JyMLv)0bgM*`T6(6JSSaZgyB@mmIc(Il74OE@8r&gX z2|yu(t;_(z6GcWnOU}$Tz_MC@t&?*z=W~cP`k%cD7Yq+@iV|BcftJXEnMTl2@gj?mNm{7TF1qIrBol%!Z?7Z zV}JzE9%>l2YIDn?D+6cm>u8A@&q-UV86Zj;6C9;9Dx3(}5+)e*f<;AmmL6EGBmI7_ zT9p$sU#HGGfV?t z-Y3QLu)F!VwN5BWPfm7!|Dur>Ucs8W1mo!I#Wy#8KlU;t#HRb>gOq&r;=o7$F(o3$ zSvw)`a%|@6t z(7ZR-Up~4ppsxpG*=N6fG*w&Vodo~#N-AB-7!|>P95NWXK#dh9Zc5tKwlwx`-s;-krA;2FcXqjsTsabDh(-~)Rp?{1;tPyOF@jfOfj(aeGT@#vi^cYLOA!xfSh z+M-e5Ba}@ac7@-MoPmyLrAE&OYDf4j=zCwL9E4tf5JHN!vi3|(N{z_888C0TYYmNZPKMg=2rHFccbfi$G?PuEHUJWr12{q7i%BafaGTQ-ih(O%l*|TuadHb`) z6DequGoLyy%dL40@|rH!TGBGe=d$MCv{191fR*5$I;fPLE{%sd4osQ+DCT6JHCHU`122MXUM|whk zRWK|1Q2@uAa-NT@-Wig9GQ4i4dVZ2)2w4UGAqV+33HN9M#eoQrKR|2Lc)ZV?N8leA z;yYRR7kJ;YOhKm$JOcK=jJe=7)c1FN6ga$d4$Tq8Xwm&828Q>yVy`Y|3HMP;plm4% z+x-~&%nikH3>StZKQ3-#Gx#C`f5fPNv?vFrFPzAPAjkx`qs9~>7II{_MUucz-sNeF zYNVlm4#2?TRpoT1C0O$>)#olFKy#bWty@nBy#CJ0?vM=Femt<4aAWFT(Z@5K_c0a@ z%8O30^6{gcIWu6F;*jnoj^}RR%?KXLY8}?o?N0 zCK8Wv1z_PF7dg%ON_{+gDk^b*_^fi!Vb6k`6-OEO5~bfAkl+F&r39R`7JU71IX#q@ zyvBt;{P)?mvGvDTHas$!|{fg zJ?U+FfR%*<)sb`wV5ltdo0ly~^mB15RJ?5oDO#^Uye{r;QBPUgLC#?xhT}a^RSmR= zCGwgO=>$hjuf`yvp|F`FYP2Z|4koVwzQ{~S1o*HE_~l!B)WQJtHjfgzb`INszkFX* zq4+MVF+A@3s>+MCvo>FU8eZxx0~gXy+smJj@!CC4mV)=dz z6lQ2Ai+ZmX0o9u?85a71^It~fbE>O_&1~zvTQh$8XxlOQ_^bYMxEbRu_FZA~uCI)H zMaF&o2jdQ0SzkQJtn7fy!(S%8Lb;*8jlY`1Nh#N|nkS_nq(eA=(SMux_5{t&FCIAW ziM5kELmw0N^^QGt&xjRqNH*qB{rFkZfPr29`c|p%U|ORRyT085AEzZX1z+6TG%vV# zIa}|;6>+Yn&<{^#b+Mh#qa*_62`8LIYC0z>*dv_R);Rn-)4Xel+W;9`M;Hx*d6qN5~4?4L>>jq%=Uti^`;qzi*kPohWNkJV-YB|n%`%J*HMAPIt@7p+JDngyuG z?qv`H=*-rrh*fhWPW$z$y!`F~TM@@eXMzhu`y+Ls!v?i~e^8S-#vg|Qi*K)qNrFEv z{OT<<4f0Z{_D4{sGc`PN5s{TJeezPRjY-u{H8GvD3x0#w4PX+wdvG>CmIClG?b)!< zze;e`^hP5nba=Sx3$0oH(!v!C-zIsbOAz#gSoF2R8eb7m+^OLHQd*6*FM^;off85lC%5yGc(T}_`>CMi~4_4$-1#2e`XLL*X8~H@mb2ep8iO*od&wXX`1mr~b zOIR5n6w(z^o;axsWE#-UM|J3Oi#uqJm_mW+80>dIywDl&OTNtoVPu30;>S?dQ>_xA z)6z13c5-C{6|q-W$9BPqRMa0jB9`zOw^#gGFWH7zaW3_1wr~R;wIO>AfOg=Sc8_rJ zcMiqI)t6sz9rcE}J#?1zfwzq!w~6&K+QcDD=feUa?jWqB&ldmoAp*!uKIZhUPYS;?|7i4fZCUB5hZrUMeNs0utZBI&FS?g9wEwHpf=FHx zDn%I}j%^xOF?|WF4jRxNAj;RAO`SdIjrU#!=jVlCD`AE5cMMw@SUAH?Hxec-7sgz~ zE6TAc8}0-;+E8&;UFay0Rt6N$QGc_06oQ|iBCN@#CT^bQy#B z@i5jA~2^%*}dnu-A?p?~qu&|MejcuEC9zE^dY7 zohlmJrVut&AwAI%eGE#JaB)}ivb~eAqJcQN6EGC4Ns&jnlDOe3C<$TA{G1*8Y4h;c zz3q@ib@h}e!_iOgZF<0T5aQl{G~&Imx`{vpgzLM^0VmxsE4zw{W$0lG$fQSInJ|X+h1?l55f>{ z!W0$Xe`IvNJ>Bs{4rA>_?76-Pd!|r{k{R4l6&WgWayfAWaE7RC+GP=cOLP7LDo$2W zWj5%zpdGhE*rq)N)~}z1Xpr6aLDZg3lLXCVZ7hvMwSql ziOi_n6rbyCMmfI!*$w7rv@t-}ZI)7~+u@sbtc z)klhi3A0O;{nCE$g@Q7ITx z;g$z6ayOgDs$3nV$bA#9O6Ou#Iv1l}Ewdd`<{Kl0Alk%H6ZmdWp1)zO znR01$9vLh%P|$H4g;bITdH-COon|kIasM0840B_H5;7&{KHh*>$s? zRZh~hx3=_0OnR|c{-aLrRsGW9qy1hw>*$W~M7Ac{v@tGnE}K3&+27rm;X(v+qj~SD zlX~w%^hxYSHi(D3H}XTN=B^nfiP)F= z2JJ_x*%z=QpGj%ybL9+-+kSm58CrGrVhW9Ys|w1W?u0=i^v^UD9G8~Yy-k-%36D8 zXizU3tg11W`k(azz|7A;TvO|XB=Yc5h2+lh+iuksclPHe-ufq=+_S2o$1nARgcnvA z|1&8}4i1;&$&GY61{E6B6k@LhWR%L}Y4~2eF=JnU^|1g}kqNYiig?zrXymwvlf`h3 zQ2by;p8Ir%c z<$Wryi`=7lCzKZmv}^@2#AJXbwTUy9$>u>~*??O1tC;DQFqyY1a973F#L$r&czidQ z)`eOkBd>LWCeqDSIkFFJqipFQ+t`B-pl#B?#4jX>F9R25h%;HUtRihf$0L8Y{0n?wJcA^(SR3?>SXLv_}F z6x`cBHg2?VN=VHRO!Ubxj>dactg+V72Job?E<2JvvpL?zKGA#z&F1c8+L3sPGH=<< zQq`PyYA~dqu{J@h+C#=GZbQ;|dk4i*va!bpLFC`xG9J7=ZK1qlR)yzp!e|H=%^LeG zGZ%Un^Fzu?%JWF|$9o1LoN}2o0_{bAL_k|oR!UNMLyF|&2$^O9*U{b<+>?EJ`>lyqEFIAk>1J0?!x~|}Vs~3=e zLiJK-_685_+Yxr{awSGLiNmv`0{{ZkfS6+?_Zq2nokL14%!A;N6#jZ|uaK1X+)Uk5 zz&+30m9iF^Y^44^RdNy>)G=VyyXfzBZ0uJr7TQ>f*8!65&eMas9*GY#9ILzWB%Q2w zI5SU$ept#)$!zLtUV9ea49r=7))lBqzm;nU`x#=m{q8nONO3kpc7VNXh24sB317e( zt*fr+bf&YD87tk7CgoWh8W2v=FWVCZZf7usr9BP9nT z1V2Sxbp5@AV(2#lLy^z8xDQLxB9-XoC>{%bUD5YpqrU0evP$>pZLz%cHZPC=(%YZP^ipr%fk47h#v_F$S+#-dbdDTT687mW{2=vZC^g42~ zeYh-2JM}w%doG4bA|krO*W) z1V_@%jmCIkY|_ZonV__Cu!d^=yxDS&$wY`{nR*p3eBY(qFbr#8Y; z+In@zIfY!~GBA%u(Qy4u@8T)D+B-slaLj^9^unIxfaWwhMq?foH*KzXt%;gM0u^=6 zHP_9Bps`LFySQ1p`RG@!At$+)DIktfKP2NA%a0LvL>v-l*Zc2+7?;H+1)NOJWpNK@ zBxsSJB51LHyB0U?ei^h_@ql>kQu)SY$N$epEx2U=kL4wm-=SBFY4giCM?#`p30*{{ z;JA^Dae3395N!(`yA6_Sq#vr-j#(rr390X|*)WdPdXFXNqR{wEm>Uc+K^AilwkbN7 zqOuv@ryt1TPWixG0{&wRxmrabNt}8yu^{( zTx(W?&}hNl7Y1dux*OrVnaL@JJm9a*E@N92^4T1$a#d+mscxQKnX{U)jZ8`TD4mVnvpNT@e$BzXLAhk;tIGp^;?vk0tu)G_H!NmrWbB&bP z$ISv_FIY%a46paLgjjsvpjvsS$_qH1RAnK58HMYy6lQJsKUQBrK7Qt4F!zr5{3G`Q zON?C#zYZfw8)j@l%H8?dJ9B~Yp!rCHcUO>dScjR)o6FPl$UQN|BpR&tNt4q7=eEMLQh*1<$7C#*fi|c^1VuGj^nBk5Jn}+v;HjWa{TB*b)S5h3E*- z$;z4o1#Nn5pDJc%`CCj=;)cDN6_EM8Gm4>FTEURWm@>yL*8xpPbd1P8~tx!c~8fg{aJ5T(wp_?y~$O7y_oWD zKeOYRn~o%5ooDWgci!MBL$ysjrksAvEPriH^vQX$J?hU|-l64*+9z7Br(3pSSQ%2o zudNm*(D6gCV6FI5_;%CAmHQ|Nslx@kQi9YTwqvI2h0iwO>7wqoEcfYv-saRX(c7&~ z^>&iK`Tdi_9-lw-co@#jx4UwGLRVJmoajoB?#e0KMCBqicU(*5Ymb>**M6L7Ts+*G zKI&#+=Eg!`o=rruPAea@!Xys0kePHWe;aOM=d%gUp`S1LL^t#4`Mo}=;mVnRwQ>$Q z$;--l@l>es>U!^WW5I`F_`g5+Hxybo6rteaWoT%~hH;9lGPr>%n5}_-Lo1jmlsHp< zg)wRft_uc=ArLRSQj&=-g;1rvnRr!I)A?e@?0BH=WyIT}m0j!Du{44N>4~jB{ zP_p$Crf^?TsCYi`%6zHA*(f3Gt>}$%`e(sDiD=mZsDXEUjedw3w!8cfYKffXJ8V7D zI|CtYK>>7B#K$>6PT-s>!ih%U1vF@H8@!dZJY#KS2Y5VNbgjdG5!h1ylyoQ>eq9vA zmCDY=bd^UR>RVTEqW89NqW>u2MO#&_pwxGlseBc{8onF_f}w;Wiry#(2!`PjMYTZY zeH>1ttehdP^#fGH?&%HiA7jx2!A_Z>RMQED%`f0Sf~l8) z>q266c$P?3UG@xrOKX@<15s5_!Pv{xkbpTK3xS~@vA)9z-;pao_U!t`<<=6~b%1uD@@ zrN9WJ)sFao%RpL|6W;iXohj--yEZiiIurwy{cAj$6Z_vSr=sgEL3zHzj(l2gji$BQ z3gcaMraJIP2qdtT>KoM<`siEN zY7@;P0i;}a(=uV+Uw4FlEH%U>tF4CtF^VG!z+>d_8m{}^lC+uCZ4($di`xW5PO4+; zz)$#(5BJH^(xIQIqY*9E02>`uqNLOZx&c4a;DrLgMgPblL3VHyQlilhab~X72GxngpaZrSri`x^I^P0Byq##LVUuuOD}iy6NeWjcb6XgT(KcZm%AFGuW;8FImO$C7UfMR zH%1q>xUB552~v(K?mQ;Ks(zfeWB@X%5c7z^>aZTPUWOlO)pRuQnmN3sBKE2Ynq2) zUFlo$PmqHpCa_xErPk$irxVnBDJo9OphyYo$^qiUEE2<>yl%vp!_bTiAlE4fSo}}} zJ{1Sj5%>cpwq{Ng49Xk@NNs9=fa++~IeU2f| z0HnWwx$rW@BhKnu8Wef*DJSE_;P?K$A~ldYS(EU|J)u-Y`u*OU9r=)$n8=@x2?+J; zD$-o*_}i(}JdhEDmxsC|PvO&-W?p9t#LcsC_c0L1NA)Z*kXyAmsH?_*`l{6Y!j?gV zb);w6=D)Rnvk)bn3bHqouz}BiXopcRi23(sak{;(`w-rttfcpl5ag@BZ4L&MhQl*_gJi?3S46O>K(teTYL=Ieo^Y>F z@}}|m3(3!zMK3vfO`kqcGMIRHQ_cw?_#WB8hGt%gj8?TGm*j_PB9djUmFtR(ZU)(Xn3HG2i>x@}FxS$$%T1m{@nMP+M1M+-ag8yYb8%QNbvja z!JpGUm=yJx8*YkHtxhHvKZmsQwuAZ7eMyD$&Oz{pVo>*(D zx-$vx8~L??*auR7T|7WDRKCvC963&+Vw3*mRB8WsQm6zfr$q(6;@Gb6j{y=37FdwD zf>X{kg9>+rttqFHBl3z>mTmqQvJJ*xRFAX3yTvcL!Qa7%BQ;dHATsrjR~dCC={hUd zSiPP*pGsEJ0WxD7&xigc5|+i&Qn_P6Vj&+S6)xQWrgDORf!N~ZE=D=i$Zu6nQ@NJDsNnF-na`B(S59aaQL{5eGP9YlsX zuY0|A;&ZHjGUKOqN6}NM_tU9(_z;LPLR1pw2s1Z=#5BK|9JNi`m|6lV@YfQ!ZMkc= zHvVh>xpSrs5%_PF08!EH2xySCGe<=OXR7LjR9JGny$nkR`D9pfjL@uw^!PC#J1vK6 zKLPo8bOczHH}4F%EHOxDfFOgLgBwC<3lDYLEsnK+=HfiNxfo+NRWmG;dLz!*c1CJ5 zW?RY1gT@T#m(CdsXRTQto^K|B^f;8ct7E?fS)dFEad=A_aLVkB4b{^MICX`P{)u&s zgy~h~jB}^KU|~6k-rfw|91u(?-HVBK#*}j$9$+Ub{d4Sa!P{2yji?NR)}wn=Qb^Fl ziz8QmQ9O$?NM|NAwVX)_Fz!E5GEqO{_XF2?loWJCJcSedg)11rW;&a!}~gbYaP$uieu9cPtmnheG^6(ihQcLLR! zS_5!4{VbsZ(#avrbW@ONW=iy8olB7We5ILxXjyO{uk2cYk?>1(po-scN;1E7bxj$O z9%l%8mGuoTQeIc$u+C=UQD%8jz)F5X?3FsO#*BU5)$lJr+qW8IeRmL#-eNq={GY41C;v`F_ew~SlI^zg1$Ehq_gO1`vXwPIUjN7ysMn502V0N)^7mi9{H;}g zXL{mCLVRkpse2RkfHkoOY=}lZGC+g|Mp;E(LpP{-SKhoW-DPJ-TYz=@?5hNI=+7CG zcd-TQar_`ol7@w&W|R+vdFQQ8(8@WWjQ zmvBwXcB!kxN|17(s$=#|)gG%FnzWdIRTm)KOC%^<$U;gw&fcbWI`;24E8JK$LHM26 zR>5w;#<#3T0|x5?Tjkmo%d0~6VtwO^OVjwljKLsc)P zP9nHYJZu=-TH8iz_kK{hpEWDWyXRAbLZ& zn|uN1(1|yqzO5G}>7ghkmiT_Da^Nf1$kZ|qbF7lOW!be`ptf8V-+n=5sYMk?W*k<( zwgAftGGlC$A+QJp7KEmGbdm*st1Xu#+l@un2=tPEEdIQFkxuyjTRy6-I}DFwr8^ZK ze;yY$+twc6nIo-B?#P={_rqo;!(AH}N78RXQOd@Y&dZ+Xr@XY;He} z%`fI8lA(z@;laV+&+!JU@y*pY0NG}HMe1LR!2aD^)K-`yxt)ZV$ zbosDwSywR1sQ=BGT4UsY?01*Q(SKY3sPknyfeWF?`JdeqGPx>@9Q#s!<=-;67PP<9 zJ*9C~ZX^#u(zyOQ4?(Q5e*ProtG?s~gyyAuwa%yAHwIw)XtITj*|SDSx@Wuzk>S;% zVy4UispIANN#datc1+--`X=$pJdToG)GVuvW)p6{(|6OkC`HVFHVsNQ`vgq#i8rJ( zS+c3qT?*I@Np3FI+PYqLM)Vmwmq&hOvblo)cI5N=Uk|BAp-#cQwxWS@BY#?Hr#`rt ze~9m(Wt<>p^eKl)EwaK!&5Q}BYwr27+QFZF@jjW8Xqeg4wJ-wQSzDD+n~4qB=W{%{ zCY!9wxJ;b5vpP_JI_}uxNhm4F13UgfB_H*1V+JJ710!kIiYdSbXQYJ9^>AYU+j&Ca z9NfJ9qHL!`4p{qwvS>KwcP{I#*o4NnmS7khsQ_>-QBqlI$_`nPFXxNhCN0m+!wF=MZ$5t_lG(~pJ??ilGW@n3_QdFHlm~Zzj8Pz-5H~A{Y^4X!&*=w` z?oee&Ho~o$gU@JMY0^3z*O4HIndtA-gBNB%wOO81T-lK)C!-inA##`Ju($_;(EJyv zdO-I8P_Mr}rzPqM34t9}QJy&iJ#hBvV(l@=2S4rdia>v~@m-eXTG}Hu? zkWZt7NxvI^9whzlxTJ-#xo;xXzMkN9`J-LVWQjX;u~$XrV0%&JRkv5A#RnPeB-ikj zoXLHiAK0xG5RE{|RDzm3Uuq_t+1rdVvo9$ax~eCc=5MF#m|(l9%kTSN^ze%Co9DP8ipnJbAk|Aq2m z+=7NBCTVc5k~FwN($J$^kkYo9;ExzL6S;oH@@*m`PmjWD9YCIs6O0a*j&^Ujim4g; zv~xaxoIICTg^g!#HsI84qck8~*SrjiDpf#Uz@B|U+E}_p0A`0XNrf(<7WCnVk4rgSp+-SW( z_heQlNsKdTk;3D!;{2|=I%tY_TwKN0dn-wQLNt!b^kFM*& zKJF_&5lbsj#hm&^>Il(^$1D%@sc6F#VhF+Q*QW^K?$k*qd32LwW=MhW`Tc}`$Xb*e z-{??R4((Q9`P*lASi^TH7c$%S78P1;nGQ>aiKNuN{w|}ou>YeZ+R^`)l4wPpxoYEo zND}S-8%eYo2&k8G@juC-UEjXXUX`>V9rev}rg#whdbiPzf)e?Tk3-90`?XhH@lyH2LW9{+!m61zYq>!4Uj zXT&nL_Wx)`tj_?pt6MJLJ`Nc-uT@!p>NK`Ui>g+E7e4y)yxGY{NiwBl9TYON4l2kc zF{)A`r%+Id<63%U?005y5A9ZC0ZQ`itc1MIZBbpJg{^&z*mArZzAT4HCF?ewPQ`oeY|OOtE;y=iz0*NHP0Hi{}v;~z7yx4+G?M&46at-EtR zOixb`X{xIDC&QG_t80e;+PvcRoa*g4nNywMvih~#p zM9!pspH1pFHT@h)PxB~9MtvKU|AWkL{YK4`mw&?re{QCbsP1k-huU9%ipN1{yJR5^ zhhp=}E`0x=N*O1%n+1Qved`*^;)chz* zY2Ta@59=`8Zz!?I?rhLoQ1CUk@zT>C@iXNk)L?pMT2`u>ONU0r$V<pfra;t@xJjJu)i6Oe;}L(JNL_h8ETWl zeVf>nmFD#&RVnx;@t$i3bRCN$|MN;cN_-dxU=i<(S1eTC^FP121WOx*B{&3I`o{>N z^r#c8I0+G6XyNq!>>i3L^6bqf_H}1UqAKV5@|$In)RDXnTS5wVlE)XY#f@J$_(YOs zMEGZAsB^%_9B6n)e^nwe8`%PvUO@rPDdyCbIr!2>`CtZ|xaQ166=FSK$NIZ(e6pYQ z+Yy=%b`~C+@pPO7p|Azvjg$sKY07q(@c!F}(g!t&=46;xaWZu<5xUS$+~w(5A0Bu0G@%5;F_fTi+=gcbfvt(O-%V|MoR~EtQe&Ld{ zkpx$jDfYVNx2?}WkxeFk{yYBwb@PRS1I6NZJm)h5pZKY(`daIO8&3xaTB1EZ$&0@A zBeh;9m?S?ce>#osf4O?yTr_PY1Q~XsYVk^rMpnXiV}u?(S_k1t`#LGz{(&S&Mi-Ac zK8kwOqA7El+U279R+z93|7V~l1@;(EY+i$%xi}9PYTJfL>6k6+8L}n}$_%pYty)NE zgMM|%CSI$Yzd@ncN#JLbY#$#$&xbXfzPX|IVc{|)f7vJAw&@6exgz%^`R`>*bVq1E z@BR1%aw0kA1qo5N1!5QgX6`E6_?{!`vmW+ojW56H&7w|!qamh*_`Y2JumNwD9d z$nIJ#&g#n@gVW_t-zu@UR#*nl^}M?3hh?O2q`hu+23h*w^k2$tOZ(fm{fTRCRu*5y zQ0d|ie`{X(V-}K}T9tjUkgUsmy>*!4i<~-gXeT_jHdWR}tSzD;))-j^Z&FP2GA!|4 zwMO`C<%XPpuu%CSOB7+qJn#@$C~~wGM_)KD_>_P~S6B*L17{oS#|o09JM|MQ#t)ej zApA#rAQp?#`ch_HSHD(-YbjWRf@A_;O1Ku7e`W|O&9TEC`B?|S*plD|Q|UJ?)e>+5 zd7R!yn}`Eh>ml6ljY=@zP{VmVe0L&@MY!hP}zxxLPFc6 zP?IOnB=0P@pNc?HviEYkaa7LoRNmyg2Xpbf)zR$f9&C#xgr0LzO?%kgvfx#Qq(`7{OOgM)SBKibUUBDnyTp1Ct;udZryblG@=+&1~8x^eIepD1W zB9|d0T&|H{?(eq9bSdLOWyIMF;itF*f3D@ea|-$aOcjG8#=KJ<>dW{XohDWyMrE}p zRc1YTGc-QV*{-S-nolC|TXT}^)+o=$mgK9uG``fqP0@|I9d_?0ckhJmb9LArT1m zR}UGYNW~liT<=rAsW+}Q7{ye-)1a8)e7H{C^H5)FF~W)ZPK#7>+Lh|Ax;q-_f89sa z!AKWL9$slMf)M^rgKIx3)mggxf9nlK@%!&II1-p=k9guh>F@?NF3$4SXSF~3*Pb#_ zg3$Z*b9Pu`Gc_-I(UT+%ir6{mU@LNDZ>rA!>PZK9GdPKaA2jUfxwFKhDmb-g>L|77 zP=gO!2=kSyRi2 z%QU<#B5iI>h^modF?6oI(KA#Z04O-}U^Yql*k+aPWoUoiyT{*k4mUfsDM(?~CmlaZ zGf|a$I5j~ucutMkDf|S8!ul6u2Hoa(QygC%gm{r=fvS%YsJ3~3jS)wmqGky;aWm2E zFMQ&B7h)m-gcEU8Ey}{Mf0tBr*T3Eu@Y}Q5o0bRMPak&L8@=FNPV)4lWpRz>8EeCbvhM9p@-}7U zK6Kz=G4e+YG~L&2uoPwI&O zNC8Aa<-!XnBg@Lmm9ruhWrwS09{y*?%;iE9ek!qp(mI!LWg)|5Tsu|F@M8}u7yjpk z+QJvsILo{fD-~pg4zrfwpp8|RD~4IVMvm2UMo#Qm z-K96T=73JKa#+=4f0eJ^f;e?Ga`+9bHOlX-MfjITVL5UVPg^k)1u+=bN7$$1?G4%r zpl@%~aLb90)(Br%1@v#Digf`wsnofLR#keuGdwv`Fj0ExSj$_6$d-)aGK2w8P}VG)c0zgji0e^L5t!G@yX4%<*uX{QMgeoMs{0b^RMqdhe;z`W{ zv^EcL=_HW8P4PuW9r8CU=B;BMm(-%x>SMX4RK-zXf0fOQP8_-BJb^R&fG37~IxBk` zTiBX}fAK_o5x!yd7H=qx)vC8L2z7k3Q<*9|53HKn5+#s`P@MsUD9 zW%dr1T6Uk@u?tl=V*MA7GV|*j5nF2p2%MO$y{PhPww6__?n%|fg;RX7QX9EqD_5+{ z73-?(e~{T351XH5&7RGEJf9I-t(XZ~oOvHwOSyD%wy~L}_@WdJzATzD>iVpbP*0cP zd)}yV2D>Q8NE;d9RhVY%#At>6%1FQD!b&Kz4}cD)@{T1=z}W<#U{!(1I0si1CH7s9$gOTQ-+z^IVCIuB}@gIe%@rMl)V% ze?*pR-VMfATa-QV-8RdW1}2nj%|`w|=;glPC3=~?KI11o)4o6Fm4?~L)K8!ZmcS%B z$esnC@VIdP+DlTvlX}@j>?RpCj^}?Ps!W^5MN(AN8`oy3nOJ7! z-DO7qb;nJM$AzEhI3?l#?L3(lxAl0Q$}UlPTxs!5$fUm6$-0L=;E1~3R{#4YR8K9T>n(mu)R`8i^;p!^-Ti+s zlG{vjB}Xdw1P6R`Y>t)|3QoUREyL9WVX+>)S4XH|9T|LsWn->-pg-_cGG51 zk45{oar_TfP&KuJSbEm#9;$tqf1gJG`XqAk%@eeS2epqwH*ta%8`Ij&U&}kwCV>ta zc~^ALnZMU{O^exjBU)Nnw|Kq9i0txP?_KrbNF^-to9RgX>pspi$v*Bgf3J_57N?m; zB$&=v1hY&78CENeOq%PFrEhgSvl6)Cy&H8rXl%DP|6*C0Hs`zKvZ^+Yf4iH1vCmAa z$54?l`)uEs?{EJ4us1C(_pz3;clX!d{hKzaY4f~wW1IBcnC}0J0i9k9==nbx(9teA zpuEDyI~OjX^-^+cJ_%rf^7!|GvNg&M>oeE9GYtz2jm!+5&E-;%RzC@0eM|g|@uWd{ z6{}k#316*PcJ}2t@A>PGfBDwZncy+q?5LSoI?%qyzz3Db{3>35%(r&u43BAVk8VP& zoY#LZo=uC>O;S8p4}Y)gn-=qoZGoX!yX*g;#bc^P9^BK0Mc=dFat8I=f3d9=cuqf? zSS$NRaI*hiH8)M37hV)&uDbi&zp))no5jR%NQyxP!_mh%Fuy(;f8SbZ8(Gl#ZSovA zUKd;6I>1beB(Kc@Rumg>!aM#ApmuY$yx#F|irgX6bDx*{gc~qCZ6<$z_?jk*yVxqo zy213{OrvS@ypQ$7Vq-q}dl!Id@wkuIZ_rpy{*6<`w7K6WohpI1p8UN6XWE?aW7}Yj z1$-z14Fd3xocXNxe=1u;WI|$HoE4~F`G%Fi%}8)|e|_bA*FT9R`f{we3IF8Cqu9*9 zZ*_ao>L|GRYm>mVNpTWm5=d6Y0)Y`g6_3>U`iOkfQD4Gydi!b8Q9t#9(%)|;)8=^+ zZ>F-FE&UrWooRDDO?&C)*IWIjnqpe5hONeG%F?62{ogKrf751m8ZZ87<6QhVes$C4 zahmk2mm8zfzc{+0X`04frDY>q{5LYsw3(kJ-JWnS&pfD@8VY9d`nvt5tDq(dX0hx> zu7YAC8~hvn*t9vV#QJe~tOWl?HkdX?z-Md0S&$#<|Dc~is-NfU{ru)mFl{c&ZtPud zY$yN4yQk%1e*h!kP=Q;RSHo-d`eOKAQr<>9Q4r$dsiXZBz1+{s4N#8JF+*NtuM-x%Sh&HX54 zgu{Xu@j~lx-=Bia?OzYj0#9kp>+t}U-RjW&YlY6Ve>ke%Bw~D{!2Ro#SJPs>a%1cf zcO-TyG9J47)t7eaHxJ~^My$Y-n>diG0@Zhdit^)26{WyQ9KTP7#glqO%Xi?49v*ma zU-&n<1g6#E+!zrnrGsW3FHr76DbDLeKIAU1aetT7o)L4a;O_t#nsm97cT7^C<)h9F zd6LT_f8XEZ`xh?=+1&|N7Z?Cg|43{&hAE&`3IsEwEYdGe~#4x!|W~bw*#?+J~Hx0ZzRRDDE3>< zget(dypcMLfP7=5m?^ujyG0;nw&djps6hzEfZ21RDQ3 z*|M8hE}1f%cMIgt9*2y`Ubh7t{6qfi3sPsron7XXxqivvWFniBQOk4v#}yH^aPN^0 ze=yedIIdQ4UlV-&n&?C?dyil(|Kc+Bp1APD#@466|E>JRm^VQ+|`5nF=z| zM+HQ7SCYQZG&Mi!D{Tl)Y^N~0ff;wKvK+oEF9p~re2AXw{8(~UGsun0C}N4#Srue1 zyZF!ShgDH^(^X5}=7EQ9jrKX;7*-|@cHG7 z4U~XNncyZ5S(cw^PP3SCc5v2N7aEwYp=0@XRH4%w)=`tTMiyMJ4l&q~x1uWAn6`;) zI34ov*j7*z$ea@AkBw_8;vurUbzU$Zb8X9IWE{s96e^As42GDOsOO&GN)bx}e|=A5 zS0JQjyP89C_%zQzDZhZO6h4YZf2Hi8ms~R=4CzoW;Ye-e@V6&9w~c6As3I-zAYe5E zTw|H9)jw)r!|Y~TV0Jo6CGiFc>>1)Pv4FYqF4^`+O1RU3ovYo(P#0NvzB=W1F59XU zt~R@Vw@`fVxK2V>uvv4Ar)L8&O^RyRs-N$uCbqwG+^Idh2pjW)<3$ zR@AxosK7=qCcudLd9AtaPkyZeYQ!nGT`wIzqP#t78vgH*_kWMPZytH>fB*cE_g1Mm z7aS^8aor_2R5mlNZSOw`ht%W-)jOFzYTlP?ffp$=Myk%M%@7z&d(f8r93C2=&qHd| z(_|qmDibbld0g$}_Yujb4UlcJ zpT;P9;oGS&2UVjsdeOY>Y3n!xv$q|;*lg^8WSA>_^efABPqNvkeCOM%rn4R zgq^Gbfs7X;_$TV7lcy?X=QbAULUgPXgiU#DJ8M6-QRc$H@F$Qiwh6}IzR(YQvb33= z=VunRKr8_s#(@{df8|DdP=SX(hchq^ZNp4`-13fDOe{=+;V!l8Tc4_1Y5;rZLQAGoEk_6uN8Gy~#R9l1B zvI4ow+Zynb{^rP)AkXV%s`+v>U%HVGw;?<^8x}v-MwtvruDKeVU|2ja7aE|-3!YPE zh?=@&>W6J{e?6sD4mDY9@x#bNEUeD(7vN~Sr(fGemaRzd{KVco1#+VM2JK57X zJ<2LUWl<0&L#j>mR!2-)ZjI;V*IaHsSKA}h?jcN`=Mh{IU4iflZ)N~zdtARdLa&MO zFDROTyt0NB6gSp7sjYs7xF}?~YP+hof`z|Wq~+=nf2;(#s)LX}E( zVPBn)f1=FS(KadqF{ZTw8_i`;a1Q1b{jAAeqYkvft$$-W5ERIRr|-uFH~LIVAagND zmmQ$%nBbO8Q)jDr`5GSF&Ejfzc1~h9EZ9&u>r$2%QH2MG>_*4*Z8c{^kNdR@4t*xj zll{fuZ11?i!#KW-P7nbU+S>GlE4?YTFgT_Ie=<1kF`AtzN0#;dL}+iOfLLx1zh2dH zS)hkl)z}}QR0uX;v?dzD;4 zy(+7jI!Ne&>%$E`kl9IEV8sd7q8v^$&J$UwyVUuTMIA27o*wJ;)aMh^DkoLUyiqYL z>@%tC-RQR5O{jN3-sk4pXir@_cN!nHe{VPM>6MWM$FaCJ??zhS@iLl#A)z5P3T_;%_bx6l>g7&~XZMs;~8{%)W(wXt7>=eqYG za}5`tJ*q=YGY#1tPxk^SnS-F_#s=9K9GSgGu|}pavsj|EWYc)!CGyCi4Q2W9h8bWp zN7+P(ip&6BG-G_BrLG```C(&he;FQbq=9u5-n|JG`n$-oDAIu3Sj9 z;1QAAJy1dDdM2wL(62+4gA=2_XK0>KZC#ukywgm6IWo0VsP)V?GIDTfe->ES>n%K> z8QGM3Mu%c-Xou&>+vMUw2%j+F0o|+dlAq%jA0iFsnJeCCFJ$r`)yN{72BDs^hTXj? zxzU|3bZr5?%xLbkP}NS3I?(|jv@dUV3&9fQHL^HkK~c%rB94WR9$EL?U}GDFt~GhY z(v;(ldO)zcH|vv((9jM$e`Hgk{U+Q7;>0KwSUT>Mpfz2tG3t+CDS9QisGrA576Q5Y zX%|)MeB&t74E}F$Pyf%Y`tioYsy%*l)#u9K$_geR7cr~8BCfkUe^z~6m2$G`g^w@; z=-j+AFU**0oi_Pln3KS{1s}M8YL?(Vkh8=AqO+F)K&DY}{TLTI11{q?xC7z6YFER* z84i^cu?hX8A{~x(5zZOl3nov_s+rRqvoV-CrQ1$~RxN1f0!;Xv<);JnS9eS=MaO=c zqi-N`D4bYBZ7(;be{ai+zTq~P>tb!InvmeuP}3HOfV&%GUd0R72m3}AD zNBS?eBV{i3X*sg0`2t1gc}Ey&x~Sl5`6+#UW87)BFiW-$f7)0Jdw7igufP5O`rH4{ z4KcrMut5|4_U+V<{Owt_VXD+nsVXT}kz8S0VEwj;aPcF2uPHaYBW`#n<%T~1U#tIw z@2gdT-P+ZJ0#4lXl`}$*!GYNlpR&6s)C~8#lXSm_r(7t7b9fWT(CJpEuPJG(_B2<+ zsTaLYC?%>-e~b&Ny0MH`4pdadjJhcHV>s$E2U#jg1Ubfu{5G)H-#t=jY&Gd;M zS79Zdwj?t}%^EmC1)1^?-i~u>TJeBQIg>ax(rGTd{_QPDE?!q>Q56oi{Isk}b!Vbn zaP`^IRrGV=03uz~!euXdyca4VVeg3AJ2#>6*T}KTbn&x0TY( zF1zTOoVd`mSlDy&8@sB>A$?PW$bS(|H1p=|GaByH8Ew6rzeh39J-41=9BF+_FcW9z zU|tTMk^~7GHF74{OO26ga%oNuKLv%uNI1@5cLsAA>Jz+sxC-yWY@MTv`ydT=W|C6@&OSbRldbnf%Sjn`# zMcczQv+(wosEBYEM;3XHbn}p#DBG8h%5oa;i(&bQ#(NGrmSsZqo5}wt;iD(?K7M3y ze{4!(_~5T|&SF*^D6W(MtTT~4o7 z69p9xHJML;4KFC$HPcoG7NG3r%qg`7f9EQPU|Mklz}?~bHo1;M+h*D1gErv3=d4LK zwC!C5qG(^ik}&xr#%DNLH$^|E{+H`tq&%6p&}{$LbM5f>+E%!^S&^uP#nPqZJ7!j)m#rVM{YpzvUX)MZxF9`eO(N;eHTqqfC9o!o%C`xYo~CJu z)%E}v?z$OAvjtlQE2}(e{n51je}~fu-FAx5@MOv*nOVGK@j?xe7{_{^7SfwKgm)aH z@32LEwngh=m8P6-t2zKqebHy1GIj9=5~v^4d{z_3fqU(Y_}q^h8Cjk*eWaeEGqs`Bh74l zk~z)^RQo(KPD*?`T~>dFlXbp!)R}FaMYLYS-Gn8nz|9P?K&8dqsrhb^MOU^mENW(x z%~%@p40}7VP|5=}%-vFoe=j(l9SWjX@m`SnHV2E{20EZKUs`JHD9KKF3!B=C&z1Od zP4hD=aaz9^b4#&H_hj!MNDJS0lN<(yyy+G4>|oL1Jm!3^dpXvv$dZNz98QkJ`9cpu zY6hilq_8FAUPDT|LX12q*rN{#6qH(01v z7vbqmd9|mFjao!tf0?A~`9wUg2|DPCQIXU!KqPB>)Y=nLW#!E>CU~@tGYtrt(itg8 zD15Q*qM(f?FHrkJt>9BBhEjG)gS$i`UY03Oh>y&Oyb4O#c+8Kntwe-O?qG4Hdx2pP;%ZIq>} zPUKh0rH9b+X8!{F7jh{Z;;LDwupcwAMs6?i)8S=wf2d}`4$U}+yxo)KdPmYYB?*g& zkI%B~!|7X3bqjC^c=93QEqL-(s&8?}MqP8}Du@w;6)vpM$JGO-N_kyc{zUzmxd+*Z zN@k-rQGGFye{N#z_2PcVh`sL$;R_k-68Kd}8FGMaKbkKxyM+aCi7vje0J$z>A7P)% z-T4&x6=9irQ=UrO$C{URTwFtll}e8j6udb1SqtRh8Zqm$Bm=cmqdWB!LA9Kz_!t_E zN<8wil~m_Z7=+`j`j!C`Mv^5A|l*l%N%p3It`b0*9wii^^`5&jX8FxEL-T$ql(7&FbweN zs)abS9a{4x-yD=e3||X{R-{bPY$@jO2eh?YtB(2iY^LP%e?I)j+zmSLY9~~u>-*ay;nVYRuS&-^0e5 ze-3I=uaA4z8d1euh7)Es46KA}lN_?FwJ4d7ELiv{^o`^t;kw;|L2V_fKH<+ozRy9a zXh2VBt71o0A~{)bfW9$vbXl+$RnK~?NDqA$SQ*}ELDm`!Fb65tsm)cx+hU*Y{dU<| zgAP?MBvWs1awi2mTwrFkgC0atOD7KAe;^8Rk(NVMFb65*P!1wKjwW$MH4fe2n|j!; z1+{>@3No`~Oxq0$1r(F0t=%L;9wwF_kZeUAhs!SE^ zmSg`kqw}UM&%RYEI&C;JkYwCcR(6QWu*ABxg51M!5a{YhCjt#{_5!(wtE-In+2qcH zFg&guom6yXUuB>OGT_Twn`r8Ef8Jp4dxU5bp13%m(~(?sb7A~&Z0Jc}1-2@I1Mk31 z*3vwUu}EQ}+Rw`BC1RO=qEsyS)iQOUM}TNmfM;mE*OMvySh+x$=#YWm)e@L;%&-b{3`5Gm20Pc+B_}QbnQ-f- z>GBeMEimEO59*Ct_5)0`Pzb0g`)W1_Pl%fsc^`#3tlbplcGn2tJ%`u>a5G0O(%JSz zb@6YiWgNNcljIBX%?zja3;!+4OYBs8P!iI)g(F|D>uOn-@>-v}PWj&qq9)wzy1IArrU=RI4t^nk z;0-Jv$f@rZ5C+DZf4jZ?9+eMf%sRuKJa&+1X2Nc1~Rvx}NR2XZ> zVpLqZ-BFq#8FgWBK`)z!v*eK83~tR0y?l2-CkJOh(}x#oUCZCYnK+9N);Cj3FJI*G z{_dl!(sOYq#Yz;8-^p-mx(oS+4ETmGC}v7kXb};P!<3z4f1zw1757O(#)XWgab>ej zPFJ?w`w7`V$L;N3ub_Xug8so?L0hi$9`_2`NpsIZ6mHC!CxQD9?L{23aO)}QDCxVy z@8ACHlABN0HlKZa+=D}s->aPpjBKgE$loX8B7Io|7P`|#6f+nc#YJwWP88R-%gK;G z%35Fz7u5*Le`rw+g9v-cq5)f11p}T43VGG~D;2hN=xWbK1s1KjtggoT_KmgBD|;ac z^!l0Z8i+{HWr`0|x%Ai>hovV31MaL6%2X&PZr|WqR(W)nFI9KxV%yX*e9mRuMOmIR ztcWh)s#OhwXo?=G;KY17WE2u78)QF3HEs+_qgZ*~evw^aI0TKsEh^5jTth)RCEul%`FQ20@n>7sNEx$~S!yGe{32&&to*_+OEh{5N z8>|n2e?0Sf(61hO`cqBC$a$eAuXnw>lq~ohi+_?;r{{BIA6?+D!f|5>?>vUFg{fA( zV_DYgmZOJc2Aa8Zq`*--L9@fS6f7;0jVvf?uk7j-zo_G=hznU zc5We8L6}ED#@_e=bGObA?jDal{B7=Xyo5cdenSyoI}k8Mj*;3!Su11aD_yWI0? zSU>jX>CZWa>G9k)PGK8A@@i3DOSOF;Wi@%Tnnzq6vUPg6B*enJpy?X|5stW>yH?YwCy@g5|$CE_iZFBs!2T zCQXR)D_2=Tk>hBwo^zODOGRNpsnObSe{3aP*rV{&sbr|cW`<=qY{zMA=IU@;S18~H z-XjQ8Y7N$GyJ_cT=gSD4JHwoJbRohCDFrZ9`0Gu?=9#lBQwGTn@5aRq7^B@%p`6@tCupzgdj8L2o>@cq%3G?C- zDko0i6cl^w2?=e_X~s3bify}}{lnne@XdT_KhMOd!Nmimh?-sCJ`kW@e{!=tuwp{) zuzPp3Cgj&h+mmCe?cyEOk<$^o?zJhKB>nEv9`=5)T-g225?AjrY$>?Om)Wp_$Cm0K z4tzQt>)#I(Ym~DV?B9a);X%&^FV1J!%HhT_v~;XsGtUPY@x{=+vk|LUADYjh#|)rz zEzc3sAM>Eu;pUXjJnZ{@e>IB8gk8@;ByAfg?55&X`hkaYIkH$72(xTu50ar|b~tzn znoNqDf$=PBz}01uCz`FZCj7p-7|X26Tvx2km**E5yOaX|X$~?K7|>;C%!RfMYU{}a zQ@)eJth!cN?gaU|K3$M3;u=3!G+g09OMe?emY5neooASbR4 z*^23vqtsswX=V3b+9CuS(e487Do_{IG-1Nj_6pQe!Wick%uJUX__&q5* zv4Np!Z@+24u0gI;S|dw=1{*O**{tOd;#n{2oP=n_NmcoF$6j1!t6Tsj8wT84^G5WW zj@djE?d;pY>UIx-f69|SJAr)XRA93#G+y)8MTOVs{)EO$Iz_T5m|Is)C*3lv)n3xA zaika<9Vx~F-#L@v>q6!(W8$7kB{nV9!h`42VqJ@dzSt%n)55I$wwqiNhwodfnUdo9+yiuN{^k&@)hvW{9e9u$Uc|&POSy{HdG|@y_)v*_;Rbh5-8_PX) zXYh(z)q5wksvk?Xw&SXfq)8DIm{}_{oInLu-OXyTlXW_>&n8RD4&;rB{Y&8S#FUq1 z31$R)GgPMee;j!DObA)hxGH1xeU`nJGO5PySOE4P!pq|3p|=68Ec=N4U-j9e^&4+x z%*eO$Qh?jSJX)Rg>#_WAdH+~g2xRo1%>PzD%=IQdv8fEYKw=)&*Q$&*X|eVEnrvgN;45^jD4Ao ztnXjU*(RHbtAl^HmyvGZ{5K>zlPP3AALL`XEe~In93B*8T!Zb;yZQ08HvwJ`nrjNb zT}S1_bK_s4rkaHO8eZe=WBA=TAAnzVv5jA3Z_Wf*6Jq{n>l`LRX`Ie?WdeY2QkH*}uVl9)h@^28&8O*V3=+ zb1g+t)iO|Gt}Mj#{jvMdIkxfgMj37?vRT&bV9z ze^Ka&j5f%zq!2f>?Rt08MCOo}fz*q35G}M1ez&oZPyjhnJPC~BN?dO>w4+i9%awax z!c%?8WgEL{H9SnMIFi~WX}K$jYi-G)FjS<|>s0|>P(Q%$c334%m%(Q(y8QF5TqDb9 zE1TjiMXvG}6#9ASl^<8IIk?!zPn*iwf3#1Wf-!~MeNYee9N1zf^F40^TGB|E?jj2M zC}kXL(}sgO%r~A&*+IeU6tR7eqJvsBN@Ctcn8v{BNqLWrD^pgHiaSLSf^TgzcS04< zH-7@rxdaVtv%%KnU$Y_nPu8p!vA?X`y*yG+9QGZ?hi7u`o`Ty(Bzbl8C3e!-f1hI- zlT;PHak#HetOB&7N4llFwyz%x54J(ZImznR1L+wji(c6y_(M;?cRHEkJ@gvAgFFKp zD-TD#=U}n-spjNYlo!7?LN><<*W5V2<+3PiF^f@hxhrkZId+Pt>|Sfzbfv9mG=L-a zko^?IxTDPt%i3da8D4Bv_!TR*fBV+hxA)SPPL+*)$!SYhj<3NuH^$!<{jQQ?AtlqQ zK_A~rO^7E7=x}rHA-#618xUNw`f%F3T5L=tKh*~@bI?E~bfbaL98;e8U|2N01gY7& zxONg;%IWC7gyDfdL(l8#2$6*&aOrkAsdx);jv;_o?#9%4^%e+YZ{=V~VpLmsgU})B5;_V2* zLAv-n*|V?C3|$7sc|b_jI24=dK?8rmbD_D;GyV?byFbM#f$_fSHXY_Cn7= zX~=FbPM>Mrk4lpZCjeo=|4^Um{QoBSZ`Y#+8n?KJ;?49f~xALc$kFV|wpM$5I( zl(evx@mH(8SL;ag_Am>q)1`j`Yppsl@X{G$l=dEu`Y|n!e#uo@Yy_y1Wcs$kUvrt( zynN|(3s!7iGrP+Sf1|{nA!RF5+)L7)71DHUAo6Y8{aJV4;{M!yMpWk**|%}Ztz~+} zH8@ReGy&2_JsW|8E6(kv#xy$CA8-2AD33JsASukhy~9mu4;bGNCaf6P@v$VB6p{ME zR!+(@>7<-n^GDm85lIT(2r1mkDOsJe?@+F>5+}m;rPYh0e;r*;JL$&UrgJMIj!NIU zDV(7&rt75VyX8Ene62&jwqdHbf2Q)aSXS#QXSH@mF}Z8xoff+kZPaN?YEtv_$KoJ} z-pKRKD7lv)$z}ta+OfM~JPx85nm2M1T=6ovoB~%o0>`dhK+lstM(+5EQdcoZRQLwf*K}MtHM-ZO#r&ee@~R;fFZ7#bfc@XKS>_=$F>`LS z)Jb&YKH-D(I&RL)ylY&^t;~`RLj9H8@g(p$=YvMFz>DH_nqS>>A3b1p^7THm%i*B{ z(JSq-%iKN$`SzpOrCW57iS{^JB#;Go`G4bNT0P0wWin>k^C2hD z&@taCe+rFgcSpw+NyauN<{}kRrV3y5afV0#Y|Hcr4NfZfD6SOx-9>83Noor2!r-M2 z$=|c0s%yeqa(+jCMl$R^J$6j*8{E2wHBc>27jCcZp-q)j%(>;uEu}(rvRveUQ? ztmuOcd8|`bLcYNE>S2;aJ3y7!=MfhIH@zu7(C#6-X=CWHI+xZ-v-3-pp3x?oQq}YV zi&Xozxf{x~Ig}~OOySqFzk*h}u(aV56E=I1rIPCXQ5=&VUvD| zXdZX6l)*kYU*SgGYA7>}I5mm}gqfkiGRoHhQ>tLAOsMwfKvss-en*rct{a&wTp)*I zRU)>H-1Bx|6BBgfqY058`A5tL=*D(DlUcAVB}$_6UQFae#(N&*5A+(JfoUIJG#wI?3jiC z79g|V$Nrkz1Gw02t?iiIvd!JNjwU^vsB@%1WXZdp@hx?HIc~6VA{B#x{^ctY_I0s? zpNy0nDH`Bw3Hwy1sNPT+4(9nee~4S1vU;;Aav$AV$~T!1nl9hu5%BTc%g8sS0YR$< zwt?KyJcmb~0u{898QK_~Yt|NMR&N*c`wf0ZH~8u2$Wu7GwW2G#wvBH6vm@<8IcF(L zrQktRHv}>hQ;d~H-Wm331wq+b8nuY-gH+79wlum+`Y|(_$=1IQf5?yWe?Kh7_NMm{ zr7Ufwf2fY^yn)ggQYIe^>2l@m;3<$owyc-c_#p~g$ishX0HLtaXa4~y;vzwmCPliw z6DG`?;F*i;JOe(_Lvu4kl%`z9#|&~fGUUd7)LI0ZeP||J@6%m5KD_Ni5M|gcTk=Ci ztAHG6bE{l-Woqm4EVQSae{QdUt(kfT1KE*xHYo$iWLbvWf+_dTmS--QN4STu&F)O3 zLT0&BrkU=2LaYV5>D#OZcAZaALa0t}Nctagbdk7@)`6;khmYayFgko(#YO1wF>3Dx z;;~>=x+B#`c_8{qD-y<+K8J!l)MV9ED-K zGxnf%Wt!a79M|O{^6phjS)SxKifX+d8IpcbB6n!SBki;vvJDPliLCZ@IR8vN>43@4Fm3A)vWZh=~}ZcpZgjC_ac4NwxLe7#= z5dBK3lnM^rc-I_Q85_>FdE%q=J?SzmQ=aE=NfRsq>s*~94yiTBApK`QRSR{J(&>+i zebA_hu(OPa2%HOGmehS5I6#R$ohe_3v$G|MF9yP16iKF)pC*mUC0 zWoJ^4ueY*f1o@UbGc^F(wF6k6nv?-cY=N==5bX$#XtVFwet?az>B@L~ah=|IUeESq-PkvzjKI*sE)-s zLU=FBvMMErjYrEPOZtpiX(2A=OAI`kL3SgHIt_Yz`-HdY55)ru8OA&gdHCDaB65_9;!Pg>f# z(j_nF$g+TJwJD;y+=SiTAB(>TQU`&CNK3)S%p3^i;6q*3#|jQU<{Tz7cGG^Lf4-CY z&s7DFa5IWrvAqCAf#S5VH{dT3>dlp$l8UtxT?f1AaQ~cEU!V_rn@O2r#k=r5e z<_iy=c`*OqRJ~(#q+Js(Jh7cjY;$6p6K7)Ewv&!++nU(6ZQIVo*4NMbt+UoSzxwX3 zjjFn?U45^;_O99*;;s&X9!MV3$(R5rVicD_&d)FE<(C{+YDwgrbcMM8Q#39WTq;O! zs8>MAaCXSlJRTRG4pcO6I0Myd`TDdS#I28doDXR9(I`tjt272<*VOF zuF|H?L$O(kZPEkB`ZSZP1)AsJ`qDN=7?@9TF0_P_H?arPbbc`4RyCD7(~khqux(%v zKLqX}zpQOJ@CAa+s($bKG6yA5J=N}Q1Mti5U^A&}V24<`*??55v6$PlBqAv=lV5g8 zbE2$;H1>@XXAHC0Xwg9F(8(7O4%_^$Pu*fmBLSmD}Z{%Xb z!%lcOX6>vU(KwFMkZj}#kz^Wl6X`vTC!gp=7s_v5T0jDRZ0QpIfoQ*>Fr({QQ zrB$CuNyoIj>^NqWnsZDWzQ`$GF}bAfimW8*FXFxPg|e7|x4D3!cU4(H>u_1t*g4v! zHf{x%wx^V8j1dX*vfQzy*}*=gaiQh7Cm4C_q_R^8>OXN(3$OzCKd$)zJBa`n0-TQ+ z6#IQ}j@tHFZr1SML5J^F(Q!%B{SwPh*2fGvN=@d(J#q~@0@TUXsj8FZEh^+?q!59v zvV=5Pg9C&bcsxqdKYgkdnVOhjf7_d>er!A&u%1w32=;(t^jf=WLd>do29=ky82^5! zn+(M_Mqg?8Gj02>l<%VmfK4^ru2oKSG;Iwu_-Tc>DC%4eYxX@j&8JL)UQ7dNXk!Gs zR{SM$hFtbg6=_b;&VjJVW-2K{yQfC^^Mt#1{(0hVeu7&`yBOtqneNTos6;dC-={FF zj@dt~;^0oByqB?ceprG7sp(64OMZ#ieYQ=xO@8G*R*j2L?n;9y0PLgCY*e22d9P;K zc&!$&1T6iI9{P`vtlg_WJB}>Zq6i1p1Z-#?jyGbOPCCfbWJi_E|ESyC_=K0|$^Vf- zt&o%p!UW@2i0auFZYn*tYQuyTFDZGV4x&Nl=}wttnb7T_nc7 zsN^;-$Vz_tr3i8N@*7>plMi* zE2F^LCPA72cM|GPett9gV-TPOZ-AoPL#I33RkfBm^cfCU2=MYY5FP8?!4tq!B?xRq z&~9rleyVSm9Vhu68a#vOx&$&uE47#{5*+UXh2V(U4ckYSV>(t#G0#Fz49u}3p#TZ7 zfFcoE{l(S)Jplla8}O?CMtOtuvuff@ONEdz92vmN9Y6AJLjf zO2M>9UsG2+Y&4EIY>f)mLifSoB4Cg{0>1PtYLM0l{{Fc{M?}J#gy9Qy_p<50C*06< zwZ3QfB%-4d&pEEQDrxS}LwI(^Rrj~3Hf=GlGr^HL8{kRt$LEj^lzUZN_&|?qtASkC zF#X)rfzR;UFdS3EyDF=reQ<(~=60U7>$+lG65<3WCgx8*CSr_R_$WUMi`C2U>nTtMIxba&llnbjcJ1-@2wZFz_~`Q03?-N_Py0T!bn5CDjBcg9G?-ZtrUy(BeNjpko}pPaq! z21clZ;YpTz$MJ+EE(*Nqpytd9Uwaje&g7o`9!j8`@~1fWv6-GXL#y!jA!EryCLh0y zg2%p`uW$7|Yf;@h6RJ+$W0%?yp8carpe|xYSk^r2zt#VYxdZOL9{k1+jULB7M+!yC zhX4ou!k1r0Vh4$z@{kLGd?YK1w%PMvMoon!?}DZaf%xGgVr$$z-|AO8ul#XC5BlE+ zbqrc&&xBT?AK14e$1?;NEgU1V_Pa{X%K9djwxd0dbMAFH%uuz-vM z!7f;kH%qLM3pPb1eqT0)NXL)zQgKc`Px3X9#8nY9!h3A7P_(9Tl)5ps1tY%%6;`;! zLbU`P*87nfvI+C)SP%wuG5qI*%EEL$U-C5xCokS#W5O912Og5_^V)K;o>l*eHUIVz zA{pg(yYSXT7nB|7CN!~9jszkB7CTEM23BPYZRDp6r%-IIX}E@m`H!*8GOAHo zlP4**7u}mIM8(W9r1&v%RqZ@ol&GH?Bi~0g*GkvUqGd^q#omu)7T`v?t!YY|YGb*Y z&^I!MztjWO7dXe|IruV`4U}AZS4)x7+?8B*v(#4yN*pyC&??A>rscc=`8@9rIC}SJ zvhr2S1`Fnxc)$-OuBxeU3w-vj0Nt5O{VmDnwVl5eq9UDEw+9_kQNtZLggYt>a-CN5 zL*eZNSN%%nTzx{Wa?I1-1r@F$YHggF0Ye@m)s7C0;F0$+I!F8F9CR_4?b5T4@Nhch z>RBv0930Ln*0g>5S=WG!Q$~TlRW+EOCo(H9YKgANkquI{dNa;joMVR}XlB1rP2Xa4 zYV=F4S07>j_qaQt=FB(5E032@nsx@|+SMx~P0g3$ z=_wQ-x$5E~vI5sH-(Q^xe&HEH%8+I3>93TLfZMLSi~64q>S0DSE_V7D$)OI?{TRVlze5x)WH1?aSF^$84y^we1ZR!`+5%&Gs<39SNaJO5m12#<#FUW}h2H}_VK5BhS}!2l&YG&{d=X?z#rvz(%8pRa zha>;lSU#fVjbHzeDquq_e|Z)f!-x!I{^F;Sgm+MAK^?#q%-)+7dro`YgdTT?Qb@pp ze`a@@hEW)D`#~O_?+(V~O$2N@Kn#Shy<$eSMh(SoN-2z`zay5gZwlhJ~@&TebKY$lkz1G0#VSi|8bWsWOJqW3AJ zpoRymT)T+joQ$_vVY(F5jClYYA;O6<-)7j}?%t>MPq&o$)7;j^CJitb8>(hf6mHla zJk=*8Djz92_O&3q-47RWs(IVI3II@}B=&zc{2YYfQfGmi8=D^d&`FAHU0_U|AdA@f zrzry$U_xDcH*bOpcAQWG$p1$X23g1O_rSbrPN;99GFrqM0qFAxX>CUZwGP^x2FBKw zSE8JHr%tf{Uqr**S^Z?dd-CA~rjyOmwkfD~4Sk-)b^>V#co9?>kJ{Tle)k-=cm7XG z*4EOtDS;RJ7W8B7FgWcv;c| zcM+m`i_BxddIU}bppEkUuZhX=RbI?=pOuh~g6TH2lo!G;Y~5AjWE0fiT%64?yI>gv7@E z)m~METh0H zDb7S~CGP}y=)j$WCcXmkc=6ptJRf!1)l|TI+KtY8z!lU%fxE#3x;*3?h+Op^5T{_= zPoVW;biF_n_ng0gy#_%)fWm%QTPT-DE_X5YzW;j0EIPgFZ>=a{Q9!w{=>UhZ=PAoX zEzB7=yx2~mVlz+|LS@^7$u~dQ2BiFc6#qk?Pw#S~n`{0EJN49*$Dl1^3*H2zfZC{< zWJ4y9yb-li8$vp=YA5yil)Gv$Q}vQ^Sw(B}cB|7Tig`PJPqeHXK+5HWT z&55fdsFuxk{~O0{w?NIjxdy@oqKQ&=?%#IG_M5U!yW0QU(Cm;{-ndxK<{_0Ryl(6LJ8s^_k+V9uTz?A)T&(llrxev2$1o z#tF#(K-K97g31v5iD3TyKk}TMlWhAvIj!AqZA8G6O*-BKeVHHg1td=E93|9aIa%Ut z3ZNVqX|(g#Dt|=|%90p0ALOYX|-SPOf#|a<)3TThh ze05cj7__G^gJXXKdQzw9I0BvIzjX)r1>Dp)4;UEM1AmMeyn#gR>bE!-S9k+o3N2ZIYORi2(B+rix}-E7jh9P<_F{X1R>0_p_aUf&sTc<2k4n3zNZ3Vm zUIb7l*mfzz^WPP&z*%kEIRa?9f$?d&56It=3R+=pJ8%tQs$-t*bLU-9l^gvGAR`Xzv`Q$jAM2Q<8|Xd{4sq*Jn#QA$n+gZ^UJ^$ z?*Ar{DL|Jmi|NK+T+)7k<=6sR z5~(wJsKfwa&oW?CstwVDJ4eudh@hMLZLuK+`AQ|{YV%cZ_yG|gGLg=*8S&pOLg zX|n0UPKo4{rSz?|_eHu}#GKQqL4{vWEc@rhA15`10QE&kp>nPVyX<#0u%tj<@{?lBH2J zF1vR$fI}2atL6r(9Sq*nWe?0J(yxt$6(rXi!5e$GlvFSS;dH6%g?zWi`{zu#Ji@=m z?E78Zkdd%o1tJFx>SJD06s#&Oaw7Z{na_M9G6HjH6oO7{y*m`Y7Ql^w)i5wTc=3l_ z04!Kw^)H%DW>sP${TjhJF7AH`JT`N5k9A$RUM2o*5j@~$IBp@Nt`@pbBKr#h0=FcG z+W%N}WK5`?ey)y(S%@7bp!U3_Sjf>4?374XUDglqY#VR-Gc@lb%q>+<98{o<>o^dx z4yoU>f_sT1Hp>pQq}SIsJwys#F4xvZ0OVOY&l@k+A|5V-8?KlhGlCuHKg~0oDyY6h zkfipnRimt}Q;!mpUf!)UtY}FIoj-B>bu{@1k>1Yx1o^QddeA_Ot!|;Ou?;Ht3kz6q zZ;g8}XJ3jpYv!k4wz6;ET^SGZU8)S@zl^Mw@qR&WUT6N=R@DYw)j&VFI!pvf)p(`!`B3XPwa4=7(kIuV!bY-C5P!2b$(KL*EH8zE^Z=|-IL6G~uJ6

t`Ih5CCG6m2Ed; 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

HLnl^8x9W5k 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%0D_s^rp|1R72Vo;H6ZX%sygYL@aUM*k7Gcs_ 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%0D7CfvB{knun`kLzl*PR3!d|Np5uN~);=_#9 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 OyG64s{tXS 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 RTikFofJR)5f68?<$n--aEy-R^7{ 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%0Dph6 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 z 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%0Ag7pSAf4KH`%!w16 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 G=KlepTyoz4 diff --git a/.yarn/cache/@usecannon-cli-npm-2.4.20-0858c1dc0e-39fa135e5d.zip b/.yarn/cache/@usecannon-cli-npm-2.4.21-6e52472173-fd2a755e2d.zip similarity index 77% rename from .yarn/cache/@usecannon-cli-npm-2.4.20-0858c1dc0e-39fa135e5d.zip rename to .yarn/cache/@usecannon-cli-npm-2.4.21-6e52472173-fd2a755e2d.zip index c071703bc17374a4799097316c514dc686e78a5c..d53f43b37e57b797b9509f063a5d1e3c7b2009d8 100644 GIT binary patch delta 34002 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 delta 3954 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.6.0" - checksum: 342818635e88b0b1fd74be5d96f46078fab65faef86d258267f10a2dd8920856123168f17cc91c737e9b91a91ac8d7d8dcb5c6151cd3d2ab3f3a75f46e7a45f3 + checksum: e37889a5e688bb87fd5a5cabd00639ac7eaa1d88742c4b77497759cbabd9e8a5384b24d05cfe4c35b9dc68ab7eaf039e28e35938a29f4504441188c914e1eaaa languageName: node linkType: hard -"@usecannon/cli@npm:^2.4.17, @usecannon/cli@npm:^2.4.20": - version: 2.4.20 - resolution: "@usecannon/cli@npm:2.4.20" +"@usecannon/cli@npm:^2.4.21": + version: 2.4.21 + resolution: "@usecannon/cli@npm:2.4.21" dependencies: "@iarna/toml": ^3.0.0 "@synthetixio/wei": ^2.74.1 - "@usecannon/builder": ^2.4.20 + "@usecannon/builder": ^2.4.21 chalk: ^4.1.2 commander: ^9.3.0 debug: ^4.3.4 @@ -3587,7 +3587,7 @@ __metadata: untildify: ^4.0.0 bin: cannon: dist/bin/cannon.js - checksum: 39fa135e5dbdee25e05735b7e273ea1670ba6c1a4ff9edabf4ae59c3c6383a2c8fcb8bb0bd5d6d72d9285b848480a0efa544206a96913076b3412b8e288b5046 + checksum: fd2a755e2d6e90a877f209c0d838da187409b81eaadeec42d3cb7256f1461d7bd53df1e5938272d88912a33276aa45a1cd68eb274ce638c703d340b0da5ebcb0 languageName: node linkType: hard @@ -8320,13 +8320,13 @@ __metadata: languageName: node linkType: hard -"hardhat-cannon@npm:2.4.17": - version: 2.4.17 - resolution: "hardhat-cannon@npm:2.4.17" +"hardhat-cannon@npm:2.4.21": + version: 2.4.21 + resolution: "hardhat-cannon@npm:2.4.21" dependencies: "@iarna/toml": ^3.0.0 - "@usecannon/builder": ^2.4.16 - "@usecannon/cli": ^2.4.17 + "@usecannon/builder": ^2.4.21 + "@usecannon/cli": ^2.4.21 adm-zip: ^0.5.9 ajv: ^8.10.0 chalk: ^4.1.2 @@ -8343,7 +8343,7 @@ __metadata: "@nomiclabs/hardhat-ethers": ^2.0.0 "@nomiclabs/hardhat-etherscan": ^3.0.0 hardhat: ^2.0.0 - checksum: d854831f532579f48aae373ab84cb4e154fbdaf4ddd8da3da30c4aa580d6778b823ba73777fc926b3519a0876fca6298dbbbcfe3c95010f878a10150efcc2f1c + checksum: f00a31c6e9838facd374f4ff785a8e3949d1a098229aba8c6f9029021feaa7704a8119e9cd73696fe71d5cb8bc059720eb97a79f6e1c13aabf010bcec2e74673 languageName: node linkType: hard @@ -15090,7 +15090,7 @@ __metadata: "@types/node": 18.11.10 "@typescript-eslint/eslint-plugin": 5.45.0 "@typescript-eslint/parser": 5.45.0 - "@usecannon/cli": ^2.4.20 + "@usecannon/cli": ^2.4.21 eslint: 8.29.0 eslint-config-prettier: 8.5.0 eslint-plugin-no-only-tests: 3.1.0 From 9321173fe74d00e368d9f536d2c577e0c14d1d15 Mon Sep 17 00:00:00 2001 From: Leonardo Massazza Date: Fri, 4 Aug 2023 19:49:27 +0100 Subject: [PATCH 29/63] Remove unused imports (#1746) --- .../contracts/interfaces/IMarketConfigurationModule.sol | 2 -- .../perps-market/contracts/interfaces/IPerpsMarketModule.sol | 2 -- markets/perps-market/contracts/mocks/FeeCollectorMock.sol | 1 - markets/perps-market/contracts/modules/AsyncOrderModule.sol | 1 - .../contracts/modules/AsyncOrderSettlementModule.sol | 5 ----- .../contracts/modules/MarketConfigurationModule.sol | 2 -- markets/perps-market/contracts/modules/PerpsMarketModule.sol | 1 - markets/perps-market/contracts/storage/AsyncOrder.sol | 1 - markets/perps-market/contracts/storage/PerpsAccount.sol | 1 - markets/perps-market/contracts/storage/PerpsMarket.sol | 3 --- markets/perps-market/contracts/storage/Position.sol | 3 --- 11 files changed, 22 deletions(-) diff --git a/markets/perps-market/contracts/interfaces/IMarketConfigurationModule.sol b/markets/perps-market/contracts/interfaces/IMarketConfigurationModule.sol index b86e6ea2af..17997d77c6 100644 --- a/markets/perps-market/contracts/interfaces/IMarketConfigurationModule.sol +++ b/markets/perps-market/contracts/interfaces/IMarketConfigurationModule.sol @@ -2,8 +2,6 @@ pragma solidity >=0.8.11 <0.9.0; import {SettlementStrategy} from "../storage/SettlementStrategy.sol"; -import {PerpsMarketConfiguration} from "../storage/PerpsMarketConfiguration.sol"; -import {OrderFee} from "../storage/OrderFee.sol"; /** * @title Module for updating configuration in relation to async order modules. diff --git a/markets/perps-market/contracts/interfaces/IPerpsMarketModule.sol b/markets/perps-market/contracts/interfaces/IPerpsMarketModule.sol index 1041767681..c50666862d 100644 --- a/markets/perps-market/contracts/interfaces/IPerpsMarketModule.sol +++ b/markets/perps-market/contracts/interfaces/IPerpsMarketModule.sol @@ -1,8 +1,6 @@ //SPDX-License-Identifier: MIT pragma solidity >=0.8.11 <0.9.0; -import {AsyncOrder} from "../storage/AsyncOrder.sol"; - /** * @title Perps market module */ diff --git a/markets/perps-market/contracts/mocks/FeeCollectorMock.sol b/markets/perps-market/contracts/mocks/FeeCollectorMock.sol index 7418edca37..545e2b3faf 100644 --- a/markets/perps-market/contracts/mocks/FeeCollectorMock.sol +++ b/markets/perps-market/contracts/mocks/FeeCollectorMock.sol @@ -1,7 +1,6 @@ //SPDX-License-Identifier: MIT pragma solidity >=0.8.11 <0.9.0; -import "@synthetixio/core-modules/contracts/interfaces/ITokenModule.sol"; import "../interfaces/external/IFeeCollector.sol"; contract FeeCollectorMock is IFeeCollector { diff --git a/markets/perps-market/contracts/modules/AsyncOrderModule.sol b/markets/perps-market/contracts/modules/AsyncOrderModule.sol index 430e8e8e48..84af91bf50 100644 --- a/markets/perps-market/contracts/modules/AsyncOrderModule.sol +++ b/markets/perps-market/contracts/modules/AsyncOrderModule.sol @@ -6,7 +6,6 @@ import {DecimalMath} from "@synthetixio/core-contracts/contracts/utils/DecimalMa import {Account} from "@synthetixio/main/contracts/storage/Account.sol"; import {AccountRBAC} from "@synthetixio/main/contracts/storage/AccountRBAC.sol"; import {IAsyncOrderModule} from "../interfaces/IAsyncOrderModule.sol"; -import {MathUtil} from "../utils/MathUtil.sol"; import {PerpsMarket} from "../storage/PerpsMarket.sol"; import {AsyncOrder} from "../storage/AsyncOrder.sol"; import {PerpsPrice} from "../storage/PerpsPrice.sol"; diff --git a/markets/perps-market/contracts/modules/AsyncOrderSettlementModule.sol b/markets/perps-market/contracts/modules/AsyncOrderSettlementModule.sol index 6d773086fe..57c157c7d5 100644 --- a/markets/perps-market/contracts/modules/AsyncOrderSettlementModule.sol +++ b/markets/perps-market/contracts/modules/AsyncOrderSettlementModule.sol @@ -4,10 +4,7 @@ pragma solidity >=0.8.11 <0.9.0; import {IAsyncOrderSettlementModule} from "../interfaces/IAsyncOrderSettlementModule.sol"; import {SafeCastU256, SafeCastI256} from "@synthetixio/core-contracts/contracts/utils/SafeCast.sol"; import {DecimalMath} from "@synthetixio/core-contracts/contracts/utils/DecimalMath.sol"; -import {Account} from "@synthetixio/main/contracts/storage/Account.sol"; -import {AccountRBAC} from "@synthetixio/main/contracts/storage/AccountRBAC.sol"; import {IPythVerifier} from "../interfaces/external/IPythVerifier.sol"; -import {IAsyncOrderModule} from "../interfaces/IAsyncOrderModule.sol"; import {PerpsAccount, SNX_USD_MARKET_ID} from "../storage/PerpsAccount.sol"; import {MathUtil} from "../utils/MathUtil.sol"; import {PerpsMarket} from "../storage/PerpsMarket.sol"; @@ -15,7 +12,6 @@ import {AsyncOrder} from "../storage/AsyncOrder.sol"; import {Position} from "../storage/Position.sol"; import {PerpsPrice} from "../storage/PerpsPrice.sol"; import {GlobalPerpsMarket} from "../storage/GlobalPerpsMarket.sol"; -import {PerpsMarketConfiguration} from "../storage/PerpsMarketConfiguration.sol"; import {SettlementStrategy} from "../storage/SettlementStrategy.sol"; import {PerpsMarketFactory} from "../storage/PerpsMarketFactory.sol"; import {GlobalPerpsMarketConfiguration} from "../storage/GlobalPerpsMarketConfiguration.sol"; @@ -33,7 +29,6 @@ contract AsyncOrderSettlementModule is IAsyncOrderSettlementModule, IMarketEvent using PerpsMarketFactory for PerpsMarketFactory.Data; using GlobalPerpsMarket for GlobalPerpsMarket.Data; using GlobalPerpsMarketConfiguration for GlobalPerpsMarketConfiguration.Data; - using PerpsMarketConfiguration for PerpsMarketConfiguration.Data; using Position for Position.Data; using SafeCastU256 for uint256; using SafeCastI256 for int256; diff --git a/markets/perps-market/contracts/modules/MarketConfigurationModule.sol b/markets/perps-market/contracts/modules/MarketConfigurationModule.sol index 320e348429..15bd4bb1ee 100644 --- a/markets/perps-market/contracts/modules/MarketConfigurationModule.sol +++ b/markets/perps-market/contracts/modules/MarketConfigurationModule.sol @@ -5,9 +5,7 @@ import {OwnableStorage} from "@synthetixio/core-contracts/contracts/ownership/Ow import {IMarketConfigurationModule} from "../interfaces/IMarketConfigurationModule.sol"; import {SettlementStrategy} from "../storage/SettlementStrategy.sol"; import {PerpsMarketConfiguration} from "../storage/PerpsMarketConfiguration.sol"; -import {PerpsMarket} from "../storage/PerpsMarket.sol"; import {PerpsPrice} from "../storage/PerpsPrice.sol"; -import {OrderFee} from "../storage/OrderFee.sol"; /** * @title Module for updating configuration in relation to async order modules. diff --git a/markets/perps-market/contracts/modules/PerpsMarketModule.sol b/markets/perps-market/contracts/modules/PerpsMarketModule.sol index 5755766c8f..c8d60b6636 100644 --- a/markets/perps-market/contracts/modules/PerpsMarketModule.sol +++ b/markets/perps-market/contracts/modules/PerpsMarketModule.sol @@ -6,7 +6,6 @@ import {PerpsMarketConfiguration} from "../storage/PerpsMarketConfiguration.sol" import {PerpsPrice} from "../storage/PerpsPrice.sol"; import {AsyncOrder} from "../storage/AsyncOrder.sol"; import {IPerpsMarketModule} from "../interfaces/IPerpsMarketModule.sol"; -import {AddressError} from "@synthetixio/core-contracts/contracts/errors/AddressError.sol"; contract PerpsMarketModule is IPerpsMarketModule { using PerpsMarket for PerpsMarket.Data; diff --git a/markets/perps-market/contracts/storage/AsyncOrder.sol b/markets/perps-market/contracts/storage/AsyncOrder.sol index 0fb6dd1e95..ddfb1f2601 100644 --- a/markets/perps-market/contracts/storage/AsyncOrder.sol +++ b/markets/perps-market/contracts/storage/AsyncOrder.sol @@ -3,7 +3,6 @@ pragma solidity >=0.8.11 <0.9.0; import {DecimalMath} from "@synthetixio/core-contracts/contracts/utils/DecimalMath.sol"; import {SafeCastI256, SafeCastU256, SafeCastI128} from "@synthetixio/core-contracts/contracts/utils/SafeCast.sol"; -import {IAsyncOrderModule} from "../interfaces/IAsyncOrderModule.sol"; import {SettlementStrategy} from "./SettlementStrategy.sol"; import {Position} from "./Position.sol"; import {PerpsMarketConfiguration} from "./PerpsMarketConfiguration.sol"; diff --git a/markets/perps-market/contracts/storage/PerpsAccount.sol b/markets/perps-market/contracts/storage/PerpsAccount.sol index 6e79ef29e7..0c7bbd9fa2 100644 --- a/markets/perps-market/contracts/storage/PerpsAccount.sol +++ b/markets/perps-market/contracts/storage/PerpsAccount.sol @@ -9,7 +9,6 @@ import {Position} from "./Position.sol"; import {PerpsMarket} from "./PerpsMarket.sol"; import {MathUtil} from "../utils/MathUtil.sol"; import {PerpsPrice} from "./PerpsPrice.sol"; -import {AsyncOrder} from "./AsyncOrder.sol"; import {PerpsMarketFactory} from "./PerpsMarketFactory.sol"; import {GlobalPerpsMarket} from "./GlobalPerpsMarket.sol"; import {GlobalPerpsMarketConfiguration} from "./GlobalPerpsMarketConfiguration.sol"; diff --git a/markets/perps-market/contracts/storage/PerpsMarket.sol b/markets/perps-market/contracts/storage/PerpsMarket.sol index 696bfa1c4b..dc5934c15e 100644 --- a/markets/perps-market/contracts/storage/PerpsMarket.sol +++ b/markets/perps-market/contracts/storage/PerpsMarket.sol @@ -3,13 +3,10 @@ pragma solidity >=0.8.11 <0.9.0; import {DecimalMath} from "@synthetixio/core-contracts/contracts/utils/DecimalMath.sol"; import {SafeCastU256, SafeCastI256, SafeCastU128} from "@synthetixio/core-contracts/contracts/utils/SafeCast.sol"; -import {AccessError} from "@synthetixio/core-contracts/contracts/errors/AccessError.sol"; -import {PerpsAccount} from "./PerpsAccount.sol"; import {Position} from "./Position.sol"; import {AsyncOrder} from "./AsyncOrder.sol"; import {PerpsMarketConfiguration} from "./PerpsMarketConfiguration.sol"; import {MathUtil} from "../utils/MathUtil.sol"; -import {OrderFee} from "./OrderFee.sol"; import {PerpsPrice} from "./PerpsPrice.sol"; /** diff --git a/markets/perps-market/contracts/storage/Position.sol b/markets/perps-market/contracts/storage/Position.sol index 61df4de0d9..43c2900176 100644 --- a/markets/perps-market/contracts/storage/Position.sol +++ b/markets/perps-market/contracts/storage/Position.sol @@ -4,8 +4,6 @@ pragma solidity >=0.8.11 <0.9.0; import {SafeCastI256, SafeCastU256, SafeCastI128, SafeCastU128} from "@synthetixio/core-contracts/contracts/utils/SafeCast.sol"; import {DecimalMath} from "@synthetixio/core-contracts/contracts/utils/DecimalMath.sol"; import {PerpsMarket} from "./PerpsMarket.sol"; -import {PerpsPrice} from "./PerpsPrice.sol"; -import {PerpsMarketConfiguration} from "./PerpsMarketConfiguration.sol"; import {MathUtil} from "../utils/MathUtil.sol"; library Position { @@ -17,7 +15,6 @@ library Position { using DecimalMath for uint256; using DecimalMath for int128; using PerpsMarket for PerpsMarket.Data; - using PerpsMarketConfiguration for PerpsMarketConfiguration.Data; struct Data { uint128 marketId; From 45bb2bd2f6155a11139af88e88d72e060931ba6a Mon Sep 17 00:00:00 2001 From: Peiman <25097709+Rickk137@users.noreply.github.com> Date: Fri, 4 Aug 2023 22:32:38 +0330 Subject: [PATCH 30/63] Perps subgraph update (#1747) * fix: perps graph issue * feat: update core subgraph core proxy * feat: update perps subgraph * Update markets/perps-market/subgraph/package.json Co-authored-by: troy (troyb.eth) --------- Co-authored-by: Sunny Vempati Co-authored-by: troy (troyb.eth) --- .../PerpsMarketProxy/PerpsMarketProxy.ts | 900 +++++++++++------- .../perps-market/subgraph/generated/schema.ts | 600 ++++++++++-- markets/perps-market/subgraph/networks.json | 4 +- markets/perps-market/subgraph/package.json | 2 +- markets/perps-market/subgraph/schema.graphql | 53 +- markets/perps-market/subgraph/src/account.ts | 32 +- .../subgraph/src/globalConfiguration.ts | 17 + markets/perps-market/subgraph/src/market.ts | 41 +- markets/perps-market/subgraph/src/orders.ts | 8 +- .../perps-market/subgraph/subgraph.base.yaml | 16 +- .../subgraph/generated/CoreProxy/CoreProxy.ts | 204 ++++ 11 files changed, 1444 insertions(+), 433 deletions(-) create mode 100644 markets/perps-market/subgraph/src/globalConfiguration.ts diff --git a/markets/perps-market/subgraph/generated/PerpsMarketProxy/PerpsMarketProxy.ts b/markets/perps-market/subgraph/generated/PerpsMarketProxy/PerpsMarketProxy.ts index f998670a3f..95774eb0db 100644 --- a/markets/perps-market/subgraph/generated/PerpsMarketProxy/PerpsMarketProxy.ts +++ b/markets/perps-market/subgraph/generated/PerpsMarketProxy/PerpsMarketProxy.ts @@ -184,42 +184,34 @@ export class Upgraded__Params { } } -export class MarketOwnerChanged extends ethereum.Event { - get params(): MarketOwnerChanged__Params { - return new MarketOwnerChanged__Params(this); +export class FactoryInitialized extends ethereum.Event { + get params(): FactoryInitialized__Params { + return new FactoryInitialized__Params(this); } } -export class MarketOwnerChanged__Params { - _event: MarketOwnerChanged; +export class FactoryInitialized__Params { + _event: FactoryInitialized; - constructor(event: MarketOwnerChanged) { + constructor(event: FactoryInitialized) { this._event = event; } - get perpsMarketId(): BigInt { + get globalPerpsMarketId(): BigInt { return this._event.parameters[0].value.toBigInt(); } - - get oldOwner(): Address { - return this._event.parameters[1].value.toAddress(); - } - - get newOwner(): Address { - return this._event.parameters[2].value.toAddress(); - } } -export class MarketOwnerNominated extends ethereum.Event { - get params(): MarketOwnerNominated__Params { - return new MarketOwnerNominated__Params(this); +export class MarketCreated extends ethereum.Event { + get params(): MarketCreated__Params { + return new MarketCreated__Params(this); } } -export class MarketOwnerNominated__Params { - _event: MarketOwnerNominated; +export class MarketCreated__Params { + _event: MarketCreated; - constructor(event: MarketOwnerNominated) { + constructor(event: MarketCreated) { this._event = event; } @@ -227,60 +219,12 @@ export class MarketOwnerNominated__Params { return this._event.parameters[0].value.toBigInt(); } - get newNominatedOwner(): Address { - return this._event.parameters[1].value.toAddress(); - } -} - -export class MarketPriceDataUpdated extends ethereum.Event { - get params(): MarketPriceDataUpdated__Params { - return new MarketPriceDataUpdated__Params(this); - } -} - -export class MarketPriceDataUpdated__Params { - _event: MarketPriceDataUpdated; - - constructor(event: MarketPriceDataUpdated) { - this._event = event; - } - - get perpsMarketId(): BigInt { - return this._event.parameters[0].value.toBigInt(); - } - - get feedId(): Bytes { - return this._event.parameters[1].value.toBytes(); - } -} - -export class MarketRegistered extends ethereum.Event { - get params(): MarketRegistered__Params { - return new MarketRegistered__Params(this); - } -} - -export class MarketRegistered__Params { - _event: MarketRegistered; - - constructor(event: MarketRegistered) { - this._event = event; - } - - get perpsMarketId(): BigInt { - return this._event.parameters[0].value.toBigInt(); - } - - get marketOwner(): Address { - return this._event.parameters[1].value.toAddress(); - } - get marketName(): string { - return this._event.parameters[2].value.toString(); + return this._event.parameters[1].value.toString(); } get marketSymbol(): string { - return this._event.parameters[3].value.toString(); + return this._event.parameters[2].value.toString(); } } @@ -314,36 +258,6 @@ export class CollateralModified__Params { } } -export class OrderCanceled extends ethereum.Event { - get params(): OrderCanceled__Params { - return new OrderCanceled__Params(this); - } -} - -export class OrderCanceled__Params { - _event: OrderCanceled; - - constructor(event: OrderCanceled) { - this._event = event; - } - - get marketId(): BigInt { - return this._event.parameters[0].value.toBigInt(); - } - - get accountId(): BigInt { - return this._event.parameters[1].value.toBigInt(); - } - - get settlementTime(): BigInt { - return this._event.parameters[2].value.toBigInt(); - } - - get acceptablePrice(): BigInt { - return this._event.parameters[3].value.toBigInt(); - } -} - export class OrderCommitted extends ethereum.Event { get params(): OrderCommitted__Params { return new OrderCommitted__Params(this); @@ -411,25 +325,29 @@ export class MarketUpdated__Params { return this._event.parameters[0].value.toBigInt(); } - get skew(): BigInt { + get price(): BigInt { return this._event.parameters[1].value.toBigInt(); } - get size(): BigInt { + get skew(): BigInt { return this._event.parameters[2].value.toBigInt(); } - get sizeDelta(): BigInt { + get size(): BigInt { return this._event.parameters[3].value.toBigInt(); } - get currentFundingRate(): BigInt { + get sizeDelta(): BigInt { return this._event.parameters[4].value.toBigInt(); } - get currentFundingVelocity(): BigInt { + get currentFundingRate(): BigInt { return this._event.parameters[5].value.toBigInt(); } + + get currentFundingVelocity(): BigInt { + return this._event.parameters[6].value.toBigInt(); + } } export class OrderSettled extends ethereum.Event { @@ -457,28 +375,40 @@ export class OrderSettled__Params { return this._event.parameters[2].value.toBigInt(); } - get sizeDelta(): BigInt { + get pnl(): BigInt { return this._event.parameters[3].value.toBigInt(); } - get newSize(): BigInt { + get sizeDelta(): BigInt { return this._event.parameters[4].value.toBigInt(); } - get collectedFees(): BigInt { + get newSize(): BigInt { return this._event.parameters[5].value.toBigInt(); } - get settlementReward(): BigInt { + get totalFees(): BigInt { return this._event.parameters[6].value.toBigInt(); } + get referralFees(): BigInt { + return this._event.parameters[7].value.toBigInt(); + } + + get collectedFees(): BigInt { + return this._event.parameters[8].value.toBigInt(); + } + + get settlementReward(): BigInt { + return this._event.parameters[9].value.toBigInt(); + } + get trackingCode(): Bytes { - return this._event.parameters[7].value.toBytes(); + return this._event.parameters[10].value.toBytes(); } get settler(): Address { - return this._event.parameters[8].value.toAddress(); + return this._event.parameters[11].value.toAddress(); } } @@ -592,6 +522,62 @@ export class FeatureFlagDenyAllSet__Params { } } +export class AccountLiquidated extends ethereum.Event { + get params(): AccountLiquidated__Params { + return new AccountLiquidated__Params(this); + } +} + +export class AccountLiquidated__Params { + _event: AccountLiquidated; + + constructor(event: AccountLiquidated) { + this._event = event; + } + + get accountId(): BigInt { + return this._event.parameters[0].value.toBigInt(); + } + + get reward(): BigInt { + return this._event.parameters[1].value.toBigInt(); + } + + get fullLiquidation(): boolean { + return this._event.parameters[2].value.toBoolean(); + } +} + +export class PositionLiquidated extends ethereum.Event { + get params(): PositionLiquidated__Params { + return new PositionLiquidated__Params(this); + } +} + +export class PositionLiquidated__Params { + _event: PositionLiquidated; + + constructor(event: PositionLiquidated) { + this._event = event; + } + + get accountId(): BigInt { + return this._event.parameters[0].value.toBigInt(); + } + + get marketId(): BigInt { + return this._event.parameters[1].value.toBigInt(); + } + + get amountLiquidated(): BigInt { + return this._event.parameters[2].value.toBigInt(); + } + + get currentPositionSize(): BigInt { + return this._event.parameters[3].value.toBigInt(); + } +} + export class FundingParametersSet extends ethereum.Event { get params(): FundingParametersSet__Params { return new FundingParametersSet__Params(this); @@ -660,16 +646,16 @@ export class LiquidationParametersSet__Params { } } -export class LockedOiRatioD18Set extends ethereum.Event { - get params(): LockedOiRatioD18Set__Params { - return new LockedOiRatioD18Set__Params(this); +export class LockedOiRatioSet extends ethereum.Event { + get params(): LockedOiRatioSet__Params { + return new LockedOiRatioSet__Params(this); } } -export class LockedOiRatioD18Set__Params { - _event: LockedOiRatioD18Set; +export class LockedOiRatioSet__Params { + _event: LockedOiRatioSet; - constructor(event: LockedOiRatioD18Set) { + constructor(event: LockedOiRatioSet) { this._event = event; } @@ -682,6 +668,28 @@ export class LockedOiRatioD18Set__Params { } } +export class MarketPriceDataUpdated extends ethereum.Event { + get params(): MarketPriceDataUpdated__Params { + return new MarketPriceDataUpdated__Params(this); + } +} + +export class MarketPriceDataUpdated__Params { + _event: MarketPriceDataUpdated; + + constructor(event: MarketPriceDataUpdated) { + this._event = event; + } + + get marketId(): BigInt { + return this._event.parameters[0].value.toBigInt(); + } + + get feedId(): Bytes { + return this._event.parameters[1].value.toBytes(); + } +} + export class MaxMarketSizeSet extends ethereum.Event { get params(): MaxMarketSizeSet__Params { return new MaxMarketSizeSet__Params(this); @@ -826,6 +834,24 @@ export class SettlementStrategyEnabled__Params { } } +export class FeeCollectorSet extends ethereum.Event { + get params(): FeeCollectorSet__Params { + return new FeeCollectorSet__Params(this); + } +} + +export class FeeCollectorSet__Params { + _event: FeeCollectorSet; + + constructor(event: FeeCollectorSet) { + this._event = event; + } + + get feeCollector(): Address { + return this._event.parameters[0].value.toAddress(); + } +} + export class LiquidationRewardGuardsSet extends ethereum.Event { get params(): LiquidationRewardGuardsSet__Params { return new LiquidationRewardGuardsSet__Params(this); @@ -870,6 +896,28 @@ export class MaxCollateralAmountSet__Params { } } +export class ReferrerShareUpdated extends ethereum.Event { + get params(): ReferrerShareUpdated__Params { + return new ReferrerShareUpdated__Params(this); + } +} + +export class ReferrerShareUpdated__Params { + _event: ReferrerShareUpdated; + + constructor(event: ReferrerShareUpdated) { + this._event = event; + } + + get referrer(): Address { + return this._event.parameters[0].value.toAddress(); + } + + get shareRatioD18(): BigInt { + return this._event.parameters[1].value.toBigInt(); + } +} + export class SynthDeductionPrioritySet extends ethereum.Event { get params(): SynthDeductionPrioritySet__Params { return new SynthDeductionPrioritySet__Params(this); @@ -942,19 +990,44 @@ export class PerpsMarketProxy__getOpenPositionResult { return map; } - getValue0(): BigInt { + getTotalPnl(): BigInt { return this.value0; } - getValue1(): BigInt { + getAccruedFunding(): BigInt { return this.value1; } - getValue2(): BigInt { + getPositionSize(): BigInt { return this.value2; } } +export class PerpsMarketProxy__getRequiredMarginsResult { + value0: BigInt; + value1: BigInt; + + constructor(value0: BigInt, value1: BigInt) { + this.value0 = value0; + this.value1 = value1; + } + + toMap(): TypedMap { + let map = new TypedMap(); + map.set('value0', ethereum.Value.fromUnsignedBigInt(this.value0)); + map.set('value1', ethereum.Value.fromUnsignedBigInt(this.value1)); + return map; + } + + getRequiredInitialMargin(): BigInt { + return this.value0; + } + + getRequiredMaintenanceMargin(): BigInt { + return this.value1; + } +} + export class PerpsMarketProxy__getMarketSummaryResultSummaryStruct extends ethereum.Tuple { get skew(): BigInt { return this[0].toBigInt(); @@ -981,12 +1054,47 @@ export class PerpsMarketProxy__getMarketSummaryResultSummaryStruct extends ether } } +export class PerpsMarketProxy__metadataResult { + value0: string; + value1: string; + + constructor(value0: string, value1: string) { + this.value0 = value0; + this.value1 = value1; + } + + toMap(): TypedMap { + let map = new TypedMap(); + map.set('value0', ethereum.Value.fromString(this.value0)); + map.set('value1', ethereum.Value.fromString(this.value1)); + return map; + } + + getName(): string { + return this.value0; + } + + getSymbol(): string { + return this.value1; + } +} + export class PerpsMarketProxy__commitOrderResultRetOrderStruct extends ethereum.Tuple { - get accountId(): BigInt { + get settlementTime(): BigInt { return this[0].toBigInt(); } + get request(): PerpsMarketProxy__commitOrderResultRetOrderRequestStruct { + return changetype(this[1].toTuple()); + } +} + +export class PerpsMarketProxy__commitOrderResultRetOrderRequestStruct extends ethereum.Tuple { get marketId(): BigInt { + return this[0].toBigInt(); + } + + get accountId(): BigInt { return this[1].toBigInt(); } @@ -998,16 +1106,16 @@ export class PerpsMarketProxy__commitOrderResultRetOrderStruct extends ethereum. return this[3].toBigInt(); } - get settlementTime(): BigInt { + get acceptablePrice(): BigInt { return this[4].toBigInt(); } - get acceptablePrice(): BigInt { - return this[5].toBigInt(); + get trackingCode(): Bytes { + return this[5].toBytes(); } - get trackingCode(): Bytes { - return this[6].toBytes(); + get referrer(): Address { + return this[6].toAddress(); } } @@ -1060,14 +1168,28 @@ export class PerpsMarketProxy__commitOrderInputCommitmentStruct extends ethereum get trackingCode(): Bytes { return this[5].toBytes(); } + + get referrer(): Address { + return this[6].toAddress(); + } } -export class PerpsMarketProxy__getOrderResultValue0Struct extends ethereum.Tuple { - get accountId(): BigInt { +export class PerpsMarketProxy__getOrderResultOrderStruct extends ethereum.Tuple { + get settlementTime(): BigInt { return this[0].toBigInt(); } + get request(): PerpsMarketProxy__getOrderResultOrderRequestStruct { + return changetype(this[1].toTuple()); + } +} + +export class PerpsMarketProxy__getOrderResultOrderRequestStruct extends ethereum.Tuple { get marketId(): BigInt { + return this[0].toBigInt(); + } + + get accountId(): BigInt { return this[1].toBigInt(); } @@ -1079,16 +1201,16 @@ export class PerpsMarketProxy__getOrderResultValue0Struct extends ethereum.Tuple return this[3].toBigInt(); } - get settlementTime(): BigInt { + get acceptablePrice(): BigInt { return this[4].toBigInt(); } - get acceptablePrice(): BigInt { - return this[5].toBigInt(); + get trackingCode(): Bytes { + return this[5].toBytes(); } - get trackingCode(): Bytes { - return this[6].toBytes(); + get referrer(): Address { + return this[6].toAddress(); } } @@ -1532,25 +1654,25 @@ export class PerpsMarketProxy extends ethereum.SmartContract { return ethereum.CallResult.fromValue(value[0].toAddress()); } - createMarket(marketName: string, marketSymbol: string, marketOwner: Address): BigInt { - let result = super.call('createMarket', 'createMarket(string,string,address):(uint128)', [ + createMarket(requestedMarketId: BigInt, marketName: string, marketSymbol: string): BigInt { + let result = super.call('createMarket', 'createMarket(uint128,string,string):(uint128)', [ + ethereum.Value.fromUnsignedBigInt(requestedMarketId), ethereum.Value.fromString(marketName), ethereum.Value.fromString(marketSymbol), - ethereum.Value.fromAddress(marketOwner), ]); return result[0].toBigInt(); } try_createMarket( + requestedMarketId: BigInt, marketName: string, - marketSymbol: string, - marketOwner: Address + marketSymbol: string ): ethereum.CallResult { - let result = super.tryCall('createMarket', 'createMarket(string,string,address):(uint128)', [ + let result = super.tryCall('createMarket', 'createMarket(uint128,string,string):(uint128)', [ + ethereum.Value.fromUnsignedBigInt(requestedMarketId), ethereum.Value.fromString(marketName), ethereum.Value.fromString(marketSymbol), - ethereum.Value.fromAddress(marketOwner), ]); if (result.reverted) { return new ethereum.CallResult(); @@ -1559,23 +1681,19 @@ export class PerpsMarketProxy extends ethereum.SmartContract { return ethereum.CallResult.fromValue(value[0].toBigInt()); } - getMarketOwner(perpsMarketId: BigInt): Address { - let result = super.call('getMarketOwner', 'getMarketOwner(uint128):(address)', [ - ethereum.Value.fromUnsignedBigInt(perpsMarketId), - ]); + initializeFactory(): BigInt { + let result = super.call('initializeFactory', 'initializeFactory():(uint128)', []); - return result[0].toAddress(); + return result[0].toBigInt(); } - try_getMarketOwner(perpsMarketId: BigInt): ethereum.CallResult

{ - let result = super.tryCall('getMarketOwner', 'getMarketOwner(uint128):(address)', [ - ethereum.Value.fromUnsignedBigInt(perpsMarketId), - ]); + try_initializeFactory(): ethereum.CallResult { + let result = super.tryCall('initializeFactory', 'initializeFactory():(uint128)', []); if (result.reverted) { return new ethereum.CallResult(); } let value = result.value; - return ethereum.CallResult.fromValue(value[0].toAddress()); + return ethereum.CallResult.fromValue(value[0].toBigInt()); } minimumCredit(perpsMarketId: BigInt): BigInt { @@ -1654,25 +1772,6 @@ export class PerpsMarketProxy extends ethereum.SmartContract { return ethereum.CallResult.fromValue(value[0].toBoolean()); } - symbol(perpsMarketId: BigInt): string { - let result = super.call('symbol', 'symbol(uint128):(string)', [ - ethereum.Value.fromUnsignedBigInt(perpsMarketId), - ]); - - return result[0].toString(); - } - - try_symbol(perpsMarketId: BigInt): ethereum.CallResult { - let result = super.tryCall('symbol', 'symbol(uint128):(string)', [ - ethereum.Value.fromUnsignedBigInt(perpsMarketId), - ]); - if (result.reverted) { - return new ethereum.CallResult(); - } - let value = result.value; - return ethereum.CallResult.fromValue(value[0].toString()); - } - getAvailableMargin(accountId: BigInt): BigInt { let result = super.call('getAvailableMargin', 'getAvailableMargin(uint128):(int256)', [ ethereum.Value.fromUnsignedBigInt(accountId), @@ -1724,7 +1823,7 @@ export class PerpsMarketProxy extends ethereum.SmartContract { getOpenPosition(accountId: BigInt, marketId: BigInt): PerpsMarketProxy__getOpenPositionResult { let result = super.call( 'getOpenPosition', - 'getOpenPosition(uint128,uint128):(int256,int256,int256)', + 'getOpenPosition(uint128,uint128):(int256,int256,int128)', [ethereum.Value.fromUnsignedBigInt(accountId), ethereum.Value.fromUnsignedBigInt(marketId)] ); @@ -1741,7 +1840,7 @@ export class PerpsMarketProxy extends ethereum.SmartContract { ): ethereum.CallResult { let result = super.tryCall( 'getOpenPosition', - 'getOpenPosition(uint128,uint128):(int256,int256,int256)', + 'getOpenPosition(uint128,uint128):(int256,int256,int128)', [ethereum.Value.fromUnsignedBigInt(accountId), ethereum.Value.fromUnsignedBigInt(marketId)] ); if (result.reverted) { @@ -1757,6 +1856,53 @@ export class PerpsMarketProxy extends ethereum.SmartContract { ); } + getRequiredMargins(accountId: BigInt): PerpsMarketProxy__getRequiredMarginsResult { + let result = super.call('getRequiredMargins', 'getRequiredMargins(uint128):(uint256,uint256)', [ + ethereum.Value.fromUnsignedBigInt(accountId), + ]); + + return new PerpsMarketProxy__getRequiredMarginsResult( + result[0].toBigInt(), + result[1].toBigInt() + ); + } + + try_getRequiredMargins( + accountId: BigInt + ): ethereum.CallResult { + let result = super.tryCall( + 'getRequiredMargins', + 'getRequiredMargins(uint128):(uint256,uint256)', + [ethereum.Value.fromUnsignedBigInt(accountId)] + ); + if (result.reverted) { + return new ethereum.CallResult(); + } + let value = result.value; + return ethereum.CallResult.fromValue( + new PerpsMarketProxy__getRequiredMarginsResult(value[0].toBigInt(), value[1].toBigInt()) + ); + } + + getWithdrawableMargin(accountId: BigInt): BigInt { + let result = super.call('getWithdrawableMargin', 'getWithdrawableMargin(uint128):(int256)', [ + ethereum.Value.fromUnsignedBigInt(accountId), + ]); + + return result[0].toBigInt(); + } + + try_getWithdrawableMargin(accountId: BigInt): ethereum.CallResult { + let result = super.tryCall('getWithdrawableMargin', 'getWithdrawableMargin(uint128):(int256)', [ + ethereum.Value.fromUnsignedBigInt(accountId), + ]); + if (result.reverted) { + return new ethereum.CallResult(); + } + let value = result.value; + return ethereum.CallResult.fromValue(value[0].toBigInt()); + } + totalAccountOpenInterest(accountId: BigInt): BigInt { let result = super.call( 'totalAccountOpenInterest', @@ -1840,7 +1986,7 @@ export class PerpsMarketProxy extends ethereum.SmartContract { } fillPrice(marketId: BigInt, orderSize: BigInt, price: BigInt): BigInt { - let result = super.call('fillPrice', 'fillPrice(uint128,int256,uint256):(uint256)', [ + let result = super.call('fillPrice', 'fillPrice(uint128,int128,uint256):(uint256)', [ ethereum.Value.fromUnsignedBigInt(marketId), ethereum.Value.fromSignedBigInt(orderSize), ethereum.Value.fromUnsignedBigInt(price), @@ -1850,7 +1996,7 @@ export class PerpsMarketProxy extends ethereum.SmartContract { } try_fillPrice(marketId: BigInt, orderSize: BigInt, price: BigInt): ethereum.CallResult { - let result = super.tryCall('fillPrice', 'fillPrice(uint128,int256,uint256):(uint256)', [ + let result = super.tryCall('fillPrice', 'fillPrice(uint128,int128,uint256):(uint256)', [ ethereum.Value.fromUnsignedBigInt(marketId), ethereum.Value.fromSignedBigInt(orderSize), ethereum.Value.fromUnsignedBigInt(price), @@ -1908,23 +2054,44 @@ export class PerpsMarketProxy extends ethereum.SmartContract { return ethereum.CallResult.fromValue(value[0].toBigInt()); } - maxOpenInterest(marketId: BigInt): BigInt { - let result = super.call('maxOpenInterest', 'maxOpenInterest(uint128):(uint256)', [ + maxOpenInterest(marketId: BigInt): BigInt { + let result = super.call('maxOpenInterest', 'maxOpenInterest(uint128):(uint256)', [ + ethereum.Value.fromUnsignedBigInt(marketId), + ]); + + return result[0].toBigInt(); + } + + try_maxOpenInterest(marketId: BigInt): ethereum.CallResult { + let result = super.tryCall('maxOpenInterest', 'maxOpenInterest(uint128):(uint256)', [ + ethereum.Value.fromUnsignedBigInt(marketId), + ]); + if (result.reverted) { + return new ethereum.CallResult(); + } + let value = result.value; + return ethereum.CallResult.fromValue(value[0].toBigInt()); + } + + metadata(marketId: BigInt): PerpsMarketProxy__metadataResult { + let result = super.call('metadata', 'metadata(uint128):(string,string)', [ ethereum.Value.fromUnsignedBigInt(marketId), ]); - return result[0].toBigInt(); + return new PerpsMarketProxy__metadataResult(result[0].toString(), result[1].toString()); } - try_maxOpenInterest(marketId: BigInt): ethereum.CallResult { - let result = super.tryCall('maxOpenInterest', 'maxOpenInterest(uint128):(uint256)', [ + try_metadata(marketId: BigInt): ethereum.CallResult { + let result = super.tryCall('metadata', 'metadata(uint128):(string,string)', [ ethereum.Value.fromUnsignedBigInt(marketId), ]); if (result.reverted) { return new ethereum.CallResult(); } let value = result.value; - return ethereum.CallResult.fromValue(value[0].toBigInt()); + return ethereum.CallResult.fromValue( + new PerpsMarketProxy__metadataResult(value[0].toString(), value[1].toString()) + ); } size(marketId: BigInt): BigInt { @@ -1970,7 +2137,7 @@ export class PerpsMarketProxy extends ethereum.SmartContract { ): PerpsMarketProxy__commitOrderResult { let result = super.call( 'commitOrder', - 'commitOrder((uint128,uint128,int128,uint128,uint256,bytes32)):((uint128,uint128,int128,uint128,uint256,uint256,bytes32),uint256)', + 'commitOrder((uint128,uint128,int128,uint128,uint256,bytes32,address)):((uint256,(uint128,uint128,int128,uint128,uint256,bytes32,address)),uint256)', [ethereum.Value.fromTuple(commitment)] ); @@ -1987,7 +2154,7 @@ export class PerpsMarketProxy extends ethereum.SmartContract { ): ethereum.CallResult { let result = super.tryCall( 'commitOrder', - 'commitOrder((uint128,uint128,int128,uint128,uint256,bytes32)):((uint128,uint128,int128,uint128,uint256,uint256,bytes32),uint256)', + 'commitOrder((uint128,uint128,int128,uint128,uint256,bytes32,address)):((uint256,(uint128,uint128,int128,uint128,uint256,bytes32,address)),uint256)', [ethereum.Value.fromTuple(commitment)] ); if (result.reverted) { @@ -2004,31 +2171,51 @@ export class PerpsMarketProxy extends ethereum.SmartContract { ); } - getOrder(marketId: BigInt, accountId: BigInt): PerpsMarketProxy__getOrderResultValue0Struct { + computeOrderFees(marketId: BigInt, sizeDelta: BigInt): BigInt { + let result = super.call('computeOrderFees', 'computeOrderFees(uint128,int128):(uint256)', [ + ethereum.Value.fromUnsignedBigInt(marketId), + ethereum.Value.fromSignedBigInt(sizeDelta), + ]); + + return result[0].toBigInt(); + } + + try_computeOrderFees(marketId: BigInt, sizeDelta: BigInt): ethereum.CallResult { + let result = super.tryCall('computeOrderFees', 'computeOrderFees(uint128,int128):(uint256)', [ + ethereum.Value.fromUnsignedBigInt(marketId), + ethereum.Value.fromSignedBigInt(sizeDelta), + ]); + if (result.reverted) { + return new ethereum.CallResult(); + } + let value = result.value; + return ethereum.CallResult.fromValue(value[0].toBigInt()); + } + + getOrder(accountId: BigInt): PerpsMarketProxy__getOrderResultOrderStruct { let result = super.call( 'getOrder', - 'getOrder(uint128,uint128):((uint128,uint128,int128,uint128,uint256,uint256,bytes32))', - [ethereum.Value.fromUnsignedBigInt(marketId), ethereum.Value.fromUnsignedBigInt(accountId)] + 'getOrder(uint128):((uint256,(uint128,uint128,int128,uint128,uint256,bytes32,address)))', + [ethereum.Value.fromUnsignedBigInt(accountId)] ); - return changetype(result[0].toTuple()); + return changetype(result[0].toTuple()); } try_getOrder( - marketId: BigInt, accountId: BigInt - ): ethereum.CallResult { + ): ethereum.CallResult { let result = super.tryCall( 'getOrder', - 'getOrder(uint128,uint128):((uint128,uint128,int128,uint128,uint256,uint256,bytes32))', - [ethereum.Value.fromUnsignedBigInt(marketId), ethereum.Value.fromUnsignedBigInt(accountId)] + 'getOrder(uint128):((uint256,(uint128,uint128,int128,uint128,uint256,bytes32,address)))', + [ethereum.Value.fromUnsignedBigInt(accountId)] ); if (result.reverted) { return new ethereum.CallResult(); } let value = result.value; return ethereum.CallResult.fromValue( - changetype(value[0].toTuple()) + changetype(value[0].toTuple()) ); } @@ -2246,16 +2433,16 @@ export class PerpsMarketProxy extends ethereum.SmartContract { ); } - getLockedOiRatioD18(marketId: BigInt): BigInt { - let result = super.call('getLockedOiRatioD18', 'getLockedOiRatioD18(uint128):(uint256)', [ + getLockedOiRatio(marketId: BigInt): BigInt { + let result = super.call('getLockedOiRatio', 'getLockedOiRatio(uint128):(uint256)', [ ethereum.Value.fromUnsignedBigInt(marketId), ]); return result[0].toBigInt(); } - try_getLockedOiRatioD18(marketId: BigInt): ethereum.CallResult { - let result = super.tryCall('getLockedOiRatioD18', 'getLockedOiRatioD18(uint128):(uint256)', [ + try_getLockedOiRatio(marketId: BigInt): ethereum.CallResult { + let result = super.tryCall('getLockedOiRatio', 'getLockedOiRatio(uint128):(uint256)', [ ethereum.Value.fromUnsignedBigInt(marketId), ]); if (result.reverted) { @@ -2340,6 +2527,21 @@ export class PerpsMarketProxy extends ethereum.SmartContract { ); } + getFeeCollector(): Address { + let result = super.call('getFeeCollector', 'getFeeCollector():(address)', []); + + return result[0].toAddress(); + } + + try_getFeeCollector(): ethereum.CallResult
{ + let result = super.tryCall('getFeeCollector', 'getFeeCollector():(address)', []); + if (result.reverted) { + return new ethereum.CallResult(); + } + let value = result.value; + return ethereum.CallResult.fromValue(value[0].toAddress()); + } + getLiquidationRewardGuards(): PerpsMarketProxy__getLiquidationRewardGuardsResult { let result = super.call( 'getLiquidationRewardGuards', @@ -2392,6 +2594,25 @@ export class PerpsMarketProxy extends ethereum.SmartContract { return ethereum.CallResult.fromValue(value[0].toBigInt()); } + getReferrerShare(referrer: Address): BigInt { + let result = super.call('getReferrerShare', 'getReferrerShare(address):(uint256)', [ + ethereum.Value.fromAddress(referrer), + ]); + + return result[0].toBigInt(); + } + + try_getReferrerShare(referrer: Address): ethereum.CallResult { + let result = super.tryCall('getReferrerShare', 'getReferrerShare(address):(uint256)', [ + ethereum.Value.fromAddress(referrer), + ]); + if (result.reverted) { + return new ethereum.CallResult(); + } + let value = result.value; + return ethereum.CallResult.fromValue(value[0].toBigInt()); + } + getSynthDeductionPriority(): Array { let result = super.call( 'getSynthDeductionPriority', @@ -2414,6 +2635,29 @@ export class PerpsMarketProxy extends ethereum.SmartContract { let value = result.value; return ethereum.CallResult.fromValue(value[0].toBigIntArray()); } + + totalGlobalCollateralValue(): BigInt { + let result = super.call( + 'totalGlobalCollateralValue', + 'totalGlobalCollateralValue():(uint256)', + [] + ); + + return result[0].toBigInt(); + } + + try_totalGlobalCollateralValue(): ethereum.CallResult { + let result = super.tryCall( + 'totalGlobalCollateralValue', + 'totalGlobalCollateralValue():(uint256)', + [] + ); + if (result.reverted) { + return new ethereum.CallResult(); + } + let value = result.value; + return ethereum.CallResult.fromValue(value[0].toBigInt()); + } } export class CreateAccountCall extends ethereum.Call { @@ -2888,36 +3132,6 @@ export class UpgradeToCall__Outputs { } } -export class AcceptMarketOwnershipCall extends ethereum.Call { - get inputs(): AcceptMarketOwnershipCall__Inputs { - return new AcceptMarketOwnershipCall__Inputs(this); - } - - get outputs(): AcceptMarketOwnershipCall__Outputs { - return new AcceptMarketOwnershipCall__Outputs(this); - } -} - -export class AcceptMarketOwnershipCall__Inputs { - _call: AcceptMarketOwnershipCall; - - constructor(call: AcceptMarketOwnershipCall) { - this._call = call; - } - - get perpsMarketId(): BigInt { - return this._call.inputValues[0].value.toBigInt(); - } -} - -export class AcceptMarketOwnershipCall__Outputs { - _call: AcceptMarketOwnershipCall; - - constructor(call: AcceptMarketOwnershipCall) { - this._call = call; - } -} - export class CreateMarketCall extends ethereum.Call { get inputs(): CreateMarketCall__Inputs { return new CreateMarketCall__Inputs(this); @@ -2935,16 +3149,16 @@ export class CreateMarketCall__Inputs { this._call = call; } - get marketName(): string { - return this._call.inputValues[0].value.toString(); + get requestedMarketId(): BigInt { + return this._call.inputValues[0].value.toBigInt(); } - get marketSymbol(): string { + get marketName(): string { return this._call.inputValues[1].value.toString(); } - get marketOwner(): Address { - return this._call.inputValues[2].value.toAddress(); + get marketSymbol(): string { + return this._call.inputValues[2].value.toString(); } } @@ -2960,38 +3174,34 @@ export class CreateMarketCall__Outputs { } } -export class NominateMarketOwnerCall extends ethereum.Call { - get inputs(): NominateMarketOwnerCall__Inputs { - return new NominateMarketOwnerCall__Inputs(this); +export class InitializeFactoryCall extends ethereum.Call { + get inputs(): InitializeFactoryCall__Inputs { + return new InitializeFactoryCall__Inputs(this); } - get outputs(): NominateMarketOwnerCall__Outputs { - return new NominateMarketOwnerCall__Outputs(this); + get outputs(): InitializeFactoryCall__Outputs { + return new InitializeFactoryCall__Outputs(this); } } -export class NominateMarketOwnerCall__Inputs { - _call: NominateMarketOwnerCall; +export class InitializeFactoryCall__Inputs { + _call: InitializeFactoryCall; - constructor(call: NominateMarketOwnerCall) { + constructor(call: InitializeFactoryCall) { this._call = call; } - - get perpsMarketId(): BigInt { - return this._call.inputValues[0].value.toBigInt(); - } - - get newNominatedOwner(): Address { - return this._call.inputValues[1].value.toAddress(); - } } -export class NominateMarketOwnerCall__Outputs { - _call: NominateMarketOwnerCall; +export class InitializeFactoryCall__Outputs { + _call: InitializeFactoryCall; - constructor(call: NominateMarketOwnerCall) { + constructor(call: InitializeFactoryCall) { this._call = call; } + + get value0(): BigInt { + return this._call.outputValues[0].value.toBigInt(); + } } export class SetSpotMarketCall extends ethereum.Call { @@ -3054,40 +3264,6 @@ export class SetSynthetixCall__Outputs { } } -export class UpdatePriceDataCall extends ethereum.Call { - get inputs(): UpdatePriceDataCall__Inputs { - return new UpdatePriceDataCall__Inputs(this); - } - - get outputs(): UpdatePriceDataCall__Outputs { - return new UpdatePriceDataCall__Outputs(this); - } -} - -export class UpdatePriceDataCall__Inputs { - _call: UpdatePriceDataCall; - - constructor(call: UpdatePriceDataCall) { - this._call = call; - } - - get perpsMarketId(): BigInt { - return this._call.inputValues[0].value.toBigInt(); - } - - get feedId(): Bytes { - return this._call.inputValues[1].value.toBytes(); - } -} - -export class UpdatePriceDataCall__Outputs { - _call: UpdatePriceDataCall; - - constructor(call: UpdatePriceDataCall) { - this._call = call; - } -} - export class ModifyCollateralCall extends ethereum.Call { get inputs(): ModifyCollateralCall__Inputs { return new ModifyCollateralCall__Inputs(this); @@ -3126,40 +3302,6 @@ export class ModifyCollateralCall__Outputs { } } -export class CancelOrderCall extends ethereum.Call { - get inputs(): CancelOrderCall__Inputs { - return new CancelOrderCall__Inputs(this); - } - - get outputs(): CancelOrderCall__Outputs { - return new CancelOrderCall__Outputs(this); - } -} - -export class CancelOrderCall__Inputs { - _call: CancelOrderCall; - - constructor(call: CancelOrderCall) { - this._call = call; - } - - get marketId(): BigInt { - return this._call.inputValues[0].value.toBigInt(); - } - - get accountId(): BigInt { - return this._call.inputValues[1].value.toBigInt(); - } -} - -export class CancelOrderCall__Outputs { - _call: CancelOrderCall; - - constructor(call: CancelOrderCall) { - this._call = call; - } -} - export class CommitOrderCall extends ethereum.Call { get inputs(): CommitOrderCall__Inputs { return new CommitOrderCall__Inputs(this); @@ -3222,14 +3364,28 @@ export class CommitOrderCallCommitmentStruct extends ethereum.Tuple { get trackingCode(): Bytes { return this[5].toBytes(); } + + get referrer(): Address { + return this[6].toAddress(); + } } export class CommitOrderCallRetOrderStruct extends ethereum.Tuple { - get accountId(): BigInt { + get settlementTime(): BigInt { return this[0].toBigInt(); } + get request(): CommitOrderCallRetOrderRequestStruct { + return changetype(this[1].toTuple()); + } +} + +export class CommitOrderCallRetOrderRequestStruct extends ethereum.Tuple { get marketId(): BigInt { + return this[0].toBigInt(); + } + + get accountId(): BigInt { return this[1].toBigInt(); } @@ -3241,16 +3397,16 @@ export class CommitOrderCallRetOrderStruct extends ethereum.Tuple { return this[3].toBigInt(); } - get settlementTime(): BigInt { + get acceptablePrice(): BigInt { return this[4].toBigInt(); } - get acceptablePrice(): BigInt { - return this[5].toBigInt(); + get trackingCode(): Bytes { + return this[5].toBytes(); } - get trackingCode(): Bytes { - return this[6].toBytes(); + get referrer(): Address { + return this[6].toAddress(); } } @@ -3832,6 +3988,70 @@ export class SetSettlementStrategyEnabledCall__Outputs { } } +export class UpdatePriceDataCall extends ethereum.Call { + get inputs(): UpdatePriceDataCall__Inputs { + return new UpdatePriceDataCall__Inputs(this); + } + + get outputs(): UpdatePriceDataCall__Outputs { + return new UpdatePriceDataCall__Outputs(this); + } +} + +export class UpdatePriceDataCall__Inputs { + _call: UpdatePriceDataCall; + + constructor(call: UpdatePriceDataCall) { + this._call = call; + } + + get perpsMarketId(): BigInt { + return this._call.inputValues[0].value.toBigInt(); + } + + get feedId(): Bytes { + return this._call.inputValues[1].value.toBytes(); + } +} + +export class UpdatePriceDataCall__Outputs { + _call: UpdatePriceDataCall; + + constructor(call: UpdatePriceDataCall) { + this._call = call; + } +} + +export class SetFeeCollectorCall extends ethereum.Call { + get inputs(): SetFeeCollectorCall__Inputs { + return new SetFeeCollectorCall__Inputs(this); + } + + get outputs(): SetFeeCollectorCall__Outputs { + return new SetFeeCollectorCall__Outputs(this); + } +} + +export class SetFeeCollectorCall__Inputs { + _call: SetFeeCollectorCall; + + constructor(call: SetFeeCollectorCall) { + this._call = call; + } + + get feeCollector(): Address { + return this._call.inputValues[0].value.toAddress(); + } +} + +export class SetFeeCollectorCall__Outputs { + _call: SetFeeCollectorCall; + + constructor(call: SetFeeCollectorCall) { + this._call = call; + } +} + export class SetLiquidationRewardGuardsCall extends ethereum.Call { get inputs(): SetLiquidationRewardGuardsCall__Inputs { return new SetLiquidationRewardGuardsCall__Inputs(this); @@ -3929,3 +4149,37 @@ export class SetSynthDeductionPriorityCall__Outputs { this._call = call; } } + +export class UpdateReferrerShareCall extends ethereum.Call { + get inputs(): UpdateReferrerShareCall__Inputs { + return new UpdateReferrerShareCall__Inputs(this); + } + + get outputs(): UpdateReferrerShareCall__Outputs { + return new UpdateReferrerShareCall__Outputs(this); + } +} + +export class UpdateReferrerShareCall__Inputs { + _call: UpdateReferrerShareCall; + + constructor(call: UpdateReferrerShareCall) { + this._call = call; + } + + get referrer(): Address { + return this._call.inputValues[0].value.toAddress(); + } + + get shareRatioD18(): BigInt { + return this._call.inputValues[1].value.toBigInt(); + } +} + +export class UpdateReferrerShareCall__Outputs { + _call: UpdateReferrerShareCall; + + constructor(call: UpdateReferrerShareCall) { + this._call = call; + } +} diff --git a/markets/perps-market/subgraph/generated/schema.ts b/markets/perps-market/subgraph/generated/schema.ts index 8e06938f52..c28cc20c9a 100644 --- a/markets/perps-market/subgraph/generated/schema.ts +++ b/markets/perps-market/subgraph/generated/schema.ts @@ -77,6 +77,193 @@ export class Account extends Entity { } } +export class LiquidatedAccount extends Entity { + constructor(id: string) { + super(); + this.set('id', Value.fromString(id)); + } + + save(): void { + let id = this.get('id'); + assert(id != null, 'Cannot save LiquidatedAccount entity without an ID'); + if (id) { + assert( + id.kind == ValueKind.STRING, + `Entities of type LiquidatedAccount must have an ID of type String but the id '${id.displayData()}' is of type ${id.displayKind()}` + ); + store.set('LiquidatedAccount', id.toString(), this); + } + } + + static loadInBlock(id: string): LiquidatedAccount | null { + return changetype(store.get_in_block('LiquidatedAccount', id)); + } + + static load(id: string): LiquidatedAccount | null { + return changetype(store.get('LiquidatedAccount', id)); + } + + get id(): string { + let value = this.get('id'); + if (!value || value.kind == ValueKind.NULL) { + throw new Error('Cannot return null for a required field.'); + } else { + return value.toString(); + } + } + + set id(value: string) { + this.set('id', Value.fromString(value)); + } + + get accountId(): BigInt { + let value = this.get('accountId'); + if (!value || value.kind == ValueKind.NULL) { + throw new Error('Cannot return null for a required field.'); + } else { + return value.toBigInt(); + } + } + + set accountId(value: BigInt) { + this.set('accountId', Value.fromBigInt(value)); + } + + get keeperLiquidationReward(): BigInt | null { + let value = this.get('keeperLiquidationReward'); + if (!value || value.kind == ValueKind.NULL) { + return null; + } else { + return value.toBigInt(); + } + } + + set keeperLiquidationReward(value: BigInt | null) { + if (!value) { + this.unset('keeperLiquidationReward'); + } else { + this.set('keeperLiquidationReward', Value.fromBigInt(value)); + } + } + + get accountFullyLiquidated(): boolean { + let value = this.get('accountFullyLiquidated'); + if (!value || value.kind == ValueKind.NULL) { + return false; + } else { + return value.toBoolean(); + } + } + + set accountFullyLiquidated(value: boolean) { + this.set('accountFullyLiquidated', Value.fromBoolean(value)); + } +} + +export class LiquidatedPosition extends Entity { + constructor(id: string) { + super(); + this.set('id', Value.fromString(id)); + } + + save(): void { + let id = this.get('id'); + assert(id != null, 'Cannot save LiquidatedPosition entity without an ID'); + if (id) { + assert( + id.kind == ValueKind.STRING, + `Entities of type LiquidatedPosition must have an ID of type String but the id '${id.displayData()}' is of type ${id.displayKind()}` + ); + store.set('LiquidatedPosition', id.toString(), this); + } + } + + static loadInBlock(id: string): LiquidatedPosition | null { + return changetype(store.get_in_block('LiquidatedPosition', id)); + } + + static load(id: string): LiquidatedPosition | null { + return changetype(store.get('LiquidatedPosition', id)); + } + + get id(): string { + let value = this.get('id'); + if (!value || value.kind == ValueKind.NULL) { + throw new Error('Cannot return null for a required field.'); + } else { + return value.toString(); + } + } + + set id(value: string) { + this.set('id', Value.fromString(value)); + } + + get accountId(): BigInt { + let value = this.get('accountId'); + if (!value || value.kind == ValueKind.NULL) { + throw new Error('Cannot return null for a required field.'); + } else { + return value.toBigInt(); + } + } + + set accountId(value: BigInt) { + this.set('accountId', Value.fromBigInt(value)); + } + + get marketId(): BigInt | null { + let value = this.get('marketId'); + if (!value || value.kind == ValueKind.NULL) { + return null; + } else { + return value.toBigInt(); + } + } + + set marketId(value: BigInt | null) { + if (!value) { + this.unset('marketId'); + } else { + this.set('marketId', Value.fromBigInt(value)); + } + } + + get amountLiquidated(): BigInt | null { + let value = this.get('amountLiquidated'); + if (!value || value.kind == ValueKind.NULL) { + return null; + } else { + return value.toBigInt(); + } + } + + set amountLiquidated(value: BigInt | null) { + if (!value) { + this.unset('amountLiquidated'); + } else { + this.set('amountLiquidated', Value.fromBigInt(value)); + } + } + + get currentPositionSize(): BigInt | null { + let value = this.get('currentPositionSize'); + if (!value || value.kind == ValueKind.NULL) { + return null; + } else { + return value.toBigInt(); + } + } + + set currentPositionSize(value: BigInt | null) { + if (!value) { + this.unset('currentPositionSize'); + } else { + this.set('currentPositionSize', Value.fromBigInt(value)); + } + } +} + export class Market extends Entity { constructor(id: string) { super(); @@ -129,8 +316,8 @@ export class Market extends Entity { this.set('perpsMarketId', Value.fromBigInt(value)); } - get marketOwner(): string | null { - let value = this.get('marketOwner'); + get marketName(): string | null { + let value = this.get('marketName'); if (!value || value.kind == ValueKind.NULL) { return null; } else { @@ -138,16 +325,16 @@ export class Market extends Entity { } } - set marketOwner(value: string | null) { + set marketName(value: string | null) { if (!value) { - this.unset('marketOwner'); + this.unset('marketName'); } else { - this.set('marketOwner', Value.fromString(value)); + this.set('marketName', Value.fromString(value)); } } - get marketName(): string | null { - let value = this.get('marketName'); + get marketSymbol(): string | null { + let value = this.get('marketSymbol'); if (!value || value.kind == ValueKind.NULL) { return null; } else { @@ -155,62 +342,130 @@ export class Market extends Entity { } } - set marketName(value: string | null) { + set marketSymbol(value: string | null) { if (!value) { - this.unset('marketName'); + this.unset('marketSymbol'); } else { - this.set('marketName', Value.fromString(value)); + this.set('marketSymbol', Value.fromString(value)); } } - get marketSymbol(): string | null { - let value = this.get('marketSymbol'); + get price(): BigInt | null { + let value = this.get('price'); if (!value || value.kind == ValueKind.NULL) { return null; } else { - return value.toString(); + return value.toBigInt(); } } - set marketSymbol(value: string | null) { + set price(value: BigInt | null) { if (!value) { - this.unset('marketSymbol'); + this.unset('price'); } else { - this.set('marketSymbol', Value.fromString(value)); + this.set('price', Value.fromBigInt(value)); } } - get feedId(): Bytes | null { - let value = this.get('feedId'); + get skew(): BigInt | null { + let value = this.get('skew'); if (!value || value.kind == ValueKind.NULL) { return null; } else { - return value.toBytes(); + return value.toBigInt(); } } - set feedId(value: Bytes | null) { + set skew(value: BigInt | null) { if (!value) { - this.unset('feedId'); + this.unset('skew'); } else { - this.set('feedId', Value.fromBytes(value)); + this.set('skew', Value.fromBigInt(value)); } } - get owner(): string | null { - let value = this.get('owner'); + get size(): BigInt | null { + let value = this.get('size'); if (!value || value.kind == ValueKind.NULL) { return null; } else { - return value.toString(); + return value.toBigInt(); } } - set owner(value: string | null) { + set size(value: BigInt | null) { if (!value) { - this.unset('owner'); + this.unset('size'); } else { - this.set('owner', Value.fromString(value)); + this.set('size', Value.fromBigInt(value)); + } + } + + get sizeDelta(): BigInt | null { + let value = this.get('sizeDelta'); + if (!value || value.kind == ValueKind.NULL) { + return null; + } else { + return value.toBigInt(); + } + } + + set sizeDelta(value: BigInt | null) { + if (!value) { + this.unset('sizeDelta'); + } else { + this.set('sizeDelta', Value.fromBigInt(value)); + } + } + + get currentFundingRate(): BigInt | null { + let value = this.get('currentFundingRate'); + if (!value || value.kind == ValueKind.NULL) { + return null; + } else { + return value.toBigInt(); + } + } + + set currentFundingRate(value: BigInt | null) { + if (!value) { + this.unset('currentFundingRate'); + } else { + this.set('currentFundingRate', Value.fromBigInt(value)); + } + } + + get currentFundingVelocity(): BigInt | null { + let value = this.get('currentFundingVelocity'); + if (!value || value.kind == ValueKind.NULL) { + return null; + } else { + return value.toBigInt(); + } + } + + set currentFundingVelocity(value: BigInt | null) { + if (!value) { + this.unset('currentFundingVelocity'); + } else { + this.set('currentFundingVelocity', Value.fromBigInt(value)); + } + } + + get feedId(): Bytes | null { + let value = this.get('feedId'); + if (!value || value.kind == ValueKind.NULL) { + return null; + } else { + return value.toBytes(); + } + } + + set feedId(value: Bytes | null) { + if (!value) { + this.unset('feedId'); + } else { + this.set('feedId', Value.fromBytes(value)); } } @@ -248,8 +503,8 @@ export class Market extends Entity { } } - get initialMarginFraction(): BigInt | null { - let value = this.get('initialMarginFraction'); + get lockedOiPercent(): BigInt | null { + let value = this.get('lockedOiPercent'); if (!value || value.kind == ValueKind.NULL) { return null; } else { @@ -257,16 +512,67 @@ export class Market extends Entity { } } - set initialMarginFraction(value: BigInt | null) { + set lockedOiPercent(value: BigInt | null) { if (!value) { - this.unset('initialMarginFraction'); + this.unset('lockedOiPercent'); } else { - this.set('initialMarginFraction', Value.fromBigInt(value)); + this.set('lockedOiPercent', Value.fromBigInt(value)); } } - get maintenanceMarginFraction(): BigInt | null { - let value = this.get('maintenanceMarginFraction'); + get marketOwner(): string | null { + let value = this.get('marketOwner'); + if (!value || value.kind == ValueKind.NULL) { + return null; + } else { + return value.toString(); + } + } + + set marketOwner(value: string | null) { + if (!value) { + this.unset('marketOwner'); + } else { + this.set('marketOwner', Value.fromString(value)); + } + } + + get owner(): string | null { + let value = this.get('owner'); + if (!value || value.kind == ValueKind.NULL) { + return null; + } else { + return value.toString(); + } + } + + set owner(value: string | null) { + if (!value) { + this.unset('owner'); + } else { + this.set('owner', Value.fromString(value)); + } + } + + get initialMarginRatioD18(): BigInt | null { + let value = this.get('initialMarginRatioD18'); + if (!value || value.kind == ValueKind.NULL) { + return null; + } else { + return value.toBigInt(); + } + } + + set initialMarginRatioD18(value: BigInt | null) { + if (!value) { + this.unset('initialMarginRatioD18'); + } else { + this.set('initialMarginRatioD18', Value.fromBigInt(value)); + } + } + + get maintenanceMarginRatioD18(): BigInt | null { + let value = this.get('maintenanceMarginRatioD18'); if (!value || value.kind == ValueKind.NULL) { return null; } else { @@ -274,11 +580,11 @@ export class Market extends Entity { } } - set maintenanceMarginFraction(value: BigInt | null) { + set maintenanceMarginRatioD18(value: BigInt | null) { if (!value) { - this.unset('maintenanceMarginFraction'); + this.unset('maintenanceMarginRatioD18'); } else { - this.set('maintenanceMarginFraction', Value.fromBigInt(value)); + this.set('maintenanceMarginRatioD18', Value.fromBigInt(value)); } } @@ -299,8 +605,8 @@ export class Market extends Entity { } } - get maxLiquidationLimitAccumulationMultiplier(): BigInt | null { - let value = this.get('maxLiquidationLimitAccumulationMultiplier'); + get maxSecondsInLiquidationWindow(): BigInt | null { + let value = this.get('maxSecondsInLiquidationWindow'); if (!value || value.kind == ValueKind.NULL) { return null; } else { @@ -308,16 +614,16 @@ export class Market extends Entity { } } - set maxLiquidationLimitAccumulationMultiplier(value: BigInt | null) { + set maxSecondsInLiquidationWindow(value: BigInt | null) { if (!value) { - this.unset('maxLiquidationLimitAccumulationMultiplier'); + this.unset('maxSecondsInLiquidationWindow'); } else { - this.set('maxLiquidationLimitAccumulationMultiplier', Value.fromBigInt(value)); + this.set('maxSecondsInLiquidationWindow', Value.fromBigInt(value)); } } - get lockedOiPercent(): BigInt | null { - let value = this.get('lockedOiPercent'); + get minimumPositionMargin(): BigInt | null { + let value = this.get('minimumPositionMargin'); if (!value || value.kind == ValueKind.NULL) { return null; } else { @@ -325,11 +631,28 @@ export class Market extends Entity { } } - set lockedOiPercent(value: BigInt | null) { + set minimumPositionMargin(value: BigInt | null) { if (!value) { - this.unset('lockedOiPercent'); + this.unset('minimumPositionMargin'); } else { - this.set('lockedOiPercent', Value.fromBigInt(value)); + this.set('minimumPositionMargin', Value.fromBigInt(value)); + } + } + + get maxLiquidationLimitAccumulationMultiplier(): BigInt | null { + let value = this.get('maxLiquidationLimitAccumulationMultiplier'); + if (!value || value.kind == ValueKind.NULL) { + return null; + } else { + return value.toBigInt(); + } + } + + set maxLiquidationLimitAccumulationMultiplier(value: BigInt | null) { + if (!value) { + this.unset('maxLiquidationLimitAccumulationMultiplier'); + } else { + this.set('maxLiquidationLimitAccumulationMultiplier', Value.fromBigInt(value)); } } @@ -366,6 +689,19 @@ export class Market extends Entity { this.set('takerFee', Value.fromBigInt(value)); } } + + get factoryInitialized(): boolean { + let value = this.get('factoryInitialized'); + if (!value || value.kind == ValueKind.NULL) { + return false; + } else { + return value.toBoolean(); + } + } + + set factoryInitialized(value: boolean) { + this.set('factoryInitialized', Value.fromBoolean(value)); + } } export class Order extends Entity { @@ -471,17 +807,21 @@ export class Order extends Entity { this.set('orderType', Value.fromI32(value)); } - get size(): BigInt { + get size(): BigInt | null { let value = this.get('size'); if (!value || value.kind == ValueKind.NULL) { - throw new Error('Cannot return null for a required field.'); + return null; } else { return value.toBigInt(); } } - set size(value: BigInt) { - this.set('size', Value.fromBigInt(value)); + set size(value: BigInt | null) { + if (!value) { + this.unset('size'); + } else { + this.set('size', Value.fromBigInt(value)); + } } get acceptablePrice(): BigInt | null { @@ -603,17 +943,21 @@ export class Order extends Entity { } } - get newSize(): BigInt { + get newSize(): BigInt | null { let value = this.get('newSize'); if (!value || value.kind == ValueKind.NULL) { - throw new Error('Cannot return null for a required field.'); + return null; } else { return value.toBigInt(); } } - set newSize(value: BigInt) { - this.set('newSize', Value.fromBigInt(value)); + set newSize(value: BigInt | null) { + if (!value) { + this.unset('newSize'); + } else { + this.set('newSize', Value.fromBigInt(value)); + } } get collectedFees(): BigInt | null { @@ -759,19 +1103,6 @@ export class SettlementStrategy extends Entity { this.set('marketId', Value.fromBigInt(value)); } - get settlementStrategyId(): BigInt { - let value = this.get('settlementStrategyId'); - if (!value || value.kind == ValueKind.NULL) { - throw new Error('Cannot return null for a required field.'); - } else { - return value.toBigInt(); - } - } - - set settlementStrategyId(value: BigInt) { - this.set('settlementStrategyId', Value.fromBigInt(value)); - } - get enabled(): boolean { let value = this.get('enabled'); if (!value || value.kind == ValueKind.NULL) { @@ -951,3 +1282,134 @@ export class SettlementStrategy extends Entity { } } } + +export class ReferrerShare extends Entity { + constructor(id: string) { + super(); + this.set('id', Value.fromString(id)); + } + + save(): void { + let id = this.get('id'); + assert(id != null, 'Cannot save ReferrerShare entity without an ID'); + if (id) { + assert( + id.kind == ValueKind.STRING, + `Entities of type ReferrerShare must have an ID of type String but the id '${id.displayData()}' is of type ${id.displayKind()}` + ); + store.set('ReferrerShare', id.toString(), this); + } + } + + static loadInBlock(id: string): ReferrerShare | null { + return changetype(store.get_in_block('ReferrerShare', id)); + } + + static load(id: string): ReferrerShare | null { + return changetype(store.get('ReferrerShare', id)); + } + + get id(): string { + let value = this.get('id'); + if (!value || value.kind == ValueKind.NULL) { + throw new Error('Cannot return null for a required field.'); + } else { + return value.toString(); + } + } + + set id(value: string) { + this.set('id', Value.fromString(value)); + } + + get referrer(): string | null { + let value = this.get('referrer'); + if (!value || value.kind == ValueKind.NULL) { + return null; + } else { + return value.toString(); + } + } + + set referrer(value: string | null) { + if (!value) { + this.unset('referrer'); + } else { + this.set('referrer', Value.fromString(value)); + } + } + + get shareRatioD18(): BigInt | null { + let value = this.get('shareRatioD18'); + if (!value || value.kind == ValueKind.NULL) { + return null; + } else { + return value.toBigInt(); + } + } + + set shareRatioD18(value: BigInt | null) { + if (!value) { + this.unset('shareRatioD18'); + } else { + this.set('shareRatioD18', Value.fromBigInt(value)); + } + } +} + +export class GlobalConfiguration extends Entity { + constructor(id: string) { + super(); + this.set('id', Value.fromString(id)); + } + + save(): void { + let id = this.get('id'); + assert(id != null, 'Cannot save GlobalConfiguration entity without an ID'); + if (id) { + assert( + id.kind == ValueKind.STRING, + `Entities of type GlobalConfiguration must have an ID of type String but the id '${id.displayData()}' is of type ${id.displayKind()}` + ); + store.set('GlobalConfiguration', id.toString(), this); + } + } + + static loadInBlock(id: string): GlobalConfiguration | null { + return changetype(store.get_in_block('GlobalConfiguration', id)); + } + + static load(id: string): GlobalConfiguration | null { + return changetype(store.get('GlobalConfiguration', id)); + } + + get id(): string { + let value = this.get('id'); + if (!value || value.kind == ValueKind.NULL) { + throw new Error('Cannot return null for a required field.'); + } else { + return value.toString(); + } + } + + set id(value: string) { + this.set('id', Value.fromString(value)); + } + + get feeCollector(): string | null { + let value = this.get('feeCollector'); + if (!value || value.kind == ValueKind.NULL) { + return null; + } else { + return value.toString(); + } + } + + set feeCollector(value: string | null) { + if (!value) { + this.unset('feeCollector'); + } else { + this.set('feeCollector', Value.fromString(value)); + } + } +} diff --git a/markets/perps-market/subgraph/networks.json b/markets/perps-market/subgraph/networks.json index ce0e262f12..8f27371358 100644 --- a/markets/perps-market/subgraph/networks.json +++ b/markets/perps-market/subgraph/networks.json @@ -1,8 +1,8 @@ { "optimism-goerli": { "PerpsMarketProxy": { - "address": "0xd78D47739Ed468a602beb11C34a2A20759bcEf4F", - "startBlock": 11669270 + "address": "0xf272382cB3BE898A8CdB1A23BE056fA2Fcf4513b", + "startBlock": 12708889 } } } diff --git a/markets/perps-market/subgraph/package.json b/markets/perps-market/subgraph/package.json index 6313db6fad..81fef99005 100644 --- a/markets/perps-market/subgraph/package.json +++ b/markets/perps-market/subgraph/package.json @@ -14,7 +14,7 @@ "build:optimism-mainnet": "echo SKIP || node ./codegen optimism-mainnet && yarn codegen && graph build --output-dir ./build/optimism-mainnet --network optimism", "deploy:optimism-mainnet": "echo SKIP || graph deploy --output-dir ./build/optimism-mainnet --network optimism --product hosted-service snx-v3/perps-market-optimism-mainnet", "build:optimism-goerli": "node ./codegen optimism-goerli && yarn codegen && graph build --output-dir ./build/optimism-goerli --network optimism-goerli", - "deploy:optimism-goerli": "graph deploy --output-dir ./build/optimism-goerli --network optimism-goerli --product hosted-service snx-v3/perps-market-optimism-goerli", + "deploy:optimism-goerli": "graph deploy --output-dir ./build/optimism-goerli --network optimism-goerli --product hosted-service snx-v3/v3-perps-opt-goerli", "test": "echo 'SKIP: No tests' || graph test", "coverage": "yarn deployments:optimism-goerli && yarn codegen && git diff --exit-code && yarn test", "create-local": "graph create --node http://localhost:8020/ snx-v3/goerli", diff --git a/markets/perps-market/subgraph/schema.graphql b/markets/perps-market/subgraph/schema.graphql index 50a7fabeb8..918eada1b7 100644 --- a/markets/perps-market/subgraph/schema.graphql +++ b/markets/perps-market/subgraph/schema.graphql @@ -4,23 +4,48 @@ type Account @entity { owner: String! } +type LiquidatedAccount @entity { + id: ID! + accountId: BigInt! + keeperLiquidationReward: BigInt + accountFullyLiquidated: Boolean +} + +type LiquidatedPosition @entity { + id: ID! + accountId: BigInt! + marketId: BigInt + amountLiquidated: BigInt + currentPositionSize: BigInt +} + type Market @entity { id: ID! perpsMarketId: BigInt! - marketOwner: String marketName: String marketSymbol: String + price: BigInt + skew: BigInt + size: BigInt + sizeDelta: BigInt + currentFundingRate: BigInt + currentFundingVelocity: BigInt feedId: Bytes - owner: String maxFundingVelocity: BigInt skewScale: BigInt - initialMarginFraction: BigInt - maintenanceMarginFraction: BigInt + lockedOiPercent: BigInt + marketOwner: String + owner: String + initialMarginRatioD18: BigInt + maintenanceMarginRatioD18: BigInt liquidationRewardRatioD18: BigInt + maxSecondsInLiquidationWindow: BigInt + minimumPositionMargin: BigInt maxLiquidationLimitAccumulationMultiplier: BigInt - lockedOiPercent: BigInt makerFee: BigInt takerFee: BigInt + + factoryInitialized: Boolean } type Order @entity { @@ -29,7 +54,7 @@ type Order @entity { accountId: BigInt amountProvided: BigInt orderType: Int - size: BigInt! + size: BigInt acceptablePrice: BigInt settlementTime: BigInt expirationTime: BigInt @@ -38,7 +63,7 @@ type Order @entity { fillPrice: BigInt accountPnlRealized: BigInt - newSize: BigInt! + newSize: BigInt collectedFees: BigInt settelementReward: BigInt settler: String @@ -51,8 +76,7 @@ type SettlementStrategy @entity { id: ID! strategyId: BigInt! marketId: BigInt! - settlementStrategyId: BigInt! - enabled: Boolean! + enabled: Boolean strategyType: Int settlementDelay: BigInt settlementWindowDuration: BigInt @@ -64,3 +88,14 @@ type SettlementStrategy @entity { minimumUsdExchangeAmount: BigInt maxRoundingLoss: BigInt } + +type ReferrerShare @entity { + id: ID! + referrer: String + shareRatioD18: BigInt +} + +type GlobalConfiguration @entity { + id: ID! + feeCollector: String +} diff --git a/markets/perps-market/subgraph/src/account.ts b/markets/perps-market/subgraph/src/account.ts index bb62e819a6..04c11af98a 100644 --- a/markets/perps-market/subgraph/src/account.ts +++ b/markets/perps-market/subgraph/src/account.ts @@ -1,6 +1,10 @@ -import { AccountCreated } from '../generated/PerpsMarketProxy/PerpsMarketProxy'; +import { + AccountCreated, + AccountLiquidated, + PositionLiquidated, +} from '../generated/PerpsMarketProxy/PerpsMarketProxy'; -import { Account } from '../generated/schema'; +import { Account, LiquidatedAccount, LiquidatedPosition } from '../generated/schema'; export function handleAccountCreated(event: AccountCreated): void { const id = event.params.accountId.toString(); @@ -11,3 +15,27 @@ export function handleAccountCreated(event: AccountCreated): void { account.owner = event.params.owner.toHexString(); account.save(); } + +export function handleAccountLiquidated(event: AccountLiquidated): void { + const id = event.transaction.hash.toHexString(); + + const account = new LiquidatedAccount(id); + + account.accountId = event.params.accountId; + account.accountFullyLiquidated = event.params.fullLiquidation; + account.keeperLiquidationReward = event.params.reward; + account.save(); +} + +export function handlePositionLiquidated(event: PositionLiquidated): void { + const id = event.transaction.hash.toHexString(); + + const account = new LiquidatedPosition(id); + + account.accountId = event.params.accountId; + account.marketId = event.params.marketId; + account.amountLiquidated = event.params.amountLiquidated; + account.currentPositionSize = event.params.currentPositionSize; + + account.save(); +} diff --git a/markets/perps-market/subgraph/src/globalConfiguration.ts b/markets/perps-market/subgraph/src/globalConfiguration.ts new file mode 100644 index 0000000000..750c56f5f6 --- /dev/null +++ b/markets/perps-market/subgraph/src/globalConfiguration.ts @@ -0,0 +1,17 @@ +import { ReferrerShareUpdated } from '../generated/PerpsMarketProxy/PerpsMarketProxy'; + +import { ReferrerShare } from '../generated/schema'; + +export function handleReferrerShareUpdated(event: ReferrerShareUpdated): void { + const id = event.params.referrer.toHexString(); + + let referrerShare = ReferrerShare.load(id); + + if (!referrerShare) { + referrerShare = new ReferrerShare(id); + } + + referrerShare.referrer = event.params.referrer.toHexString(); + referrerShare.shareRatioD18 = event.params.shareRatioD18; + referrerShare.save(); +} diff --git a/markets/perps-market/subgraph/src/market.ts b/markets/perps-market/subgraph/src/market.ts index c3c885742e..cf5e23d455 100644 --- a/markets/perps-market/subgraph/src/market.ts +++ b/markets/perps-market/subgraph/src/market.ts @@ -1,42 +1,45 @@ import { MarketPriceDataUpdated, - MarketOwnerChanged, - MarketRegistered, + MarketCreated, FundingParametersSet, LiquidationParametersSet, - LockedOiRatioD18Set, + LockedOiRatioSet, OrderFeesSet, + MarketUpdated, + FactoryInitialized, } from '../generated/PerpsMarketProxy/PerpsMarketProxy'; import { Market } from '../generated/schema'; -export function handleMarketRegistered(event: MarketRegistered): void { +export function handleMarketCreated(event: MarketCreated): void { const id = event.params.perpsMarketId.toString(); const market = new Market(id); market.perpsMarketId = event.params.perpsMarketId; - market.marketOwner = event.params.marketOwner.toHexString(); market.marketName = event.params.marketName; market.marketSymbol = event.params.marketSymbol; market.save(); } -export function handleMarketPriceDataUpdated(event: MarketPriceDataUpdated): void { - const id = event.params.perpsMarketId.toString(); - const market = Market.load(id); +export function handleMarketUpdated(event: MarketUpdated): void { + const id = event.params.marketId.toString(); + const market = new Market(id); - if (market) { - market.feedId = event.params.feedId; - market.save(); - } + market.price = event.params.price; + market.skew = event.params.skew; + market.size = event.params.size; + market.sizeDelta = event.params.sizeDelta; + market.currentFundingRate = event.params.currentFundingRate; + market.currentFundingVelocity = event.params.currentFundingVelocity; + market.save(); } -export function handleMarketOwnerChanged(event: MarketOwnerChanged): void { - const id = event.params.perpsMarketId.toString(); +export function handleMarketPriceDataUpdated(event: MarketPriceDataUpdated): void { + const id = event.params.marketId.toString(); const market = Market.load(id); if (market) { - market.owner = event.params.newOwner.toHexString(); + market.feedId = event.params.feedId; market.save(); } } @@ -52,7 +55,7 @@ export function handleFundingParametersSet(event: FundingParametersSet): void { } } -export function handleLockedOiRatioD18Set(event: LockedOiRatioD18Set): void { +export function handleLockedOiRatioSet(event: LockedOiRatioSet): void { const id = event.params.marketId.toString(); const market = Market.load(id); @@ -67,9 +70,11 @@ export function handleLiquidationParametersSet(event: LiquidationParametersSet): const market = Market.load(id); if (market) { - market.initialMarginFraction = event.params.initialMarginRatioD18; + market.initialMarginRatioD18 = event.params.initialMarginRatioD18; market.liquidationRewardRatioD18 = event.params.liquidationRewardRatioD18; - market.maintenanceMarginFraction = event.params.maintenanceMarginRatioD18; + market.maintenanceMarginRatioD18 = event.params.maintenanceMarginRatioD18; + market.maxSecondsInLiquidationWindow = event.params.maxSecondsInLiquidationWindow; + market.minimumPositionMargin = event.params.minimumPositionMargin; market.maxLiquidationLimitAccumulationMultiplier = event.params.maxLiquidationLimitAccumulationMultiplier; market.save(); diff --git a/markets/perps-market/subgraph/src/orders.ts b/markets/perps-market/subgraph/src/orders.ts index 7c2aa95c04..ea6855da63 100644 --- a/markets/perps-market/subgraph/src/orders.ts +++ b/markets/perps-market/subgraph/src/orders.ts @@ -9,7 +9,9 @@ export function handleOrderCommitted(event: OrderCommitted): void { '-' + event.params.marketId.toString() + '-' + - event.params.accountId.toString(); + event.params.accountId.toString() + + '-' + + event.block.number.toString(); let order = Order.load(id); @@ -26,9 +28,7 @@ export function handleOrderCommitted(event: OrderCommitted): void { order.expirationTime = event.params.expirationTime; order.trackingCode = event.params.trackingCode; order.owner = event.params.sender.toHexString(); - - const sizeDelta = BigInt.fromString(event.params.sizeDelta.toString()); - order.size = order.size.plus(sizeDelta); + order.size = event.params.sizeDelta; order.block = event.block.number; order.timestamp = event.block.timestamp; diff --git a/markets/perps-market/subgraph/subgraph.base.yaml b/markets/perps-market/subgraph/subgraph.base.yaml index 9b0ea31e9e..d7562dae63 100644 --- a/markets/perps-market/subgraph/subgraph.base.yaml +++ b/markets/perps-market/subgraph/subgraph.base.yaml @@ -15,22 +15,25 @@ dataSources: file: ./deployments/optimism-goerli/PerpsMarketProxy.json entities: - Account + - LiquidatedAccount - Market - Order - SettlementStrategy eventHandlers: - event: AccountCreated(indexed uint128,indexed address) handler: handleAccountCreated - - event: MarketRegistered(indexed uint128,indexed address,string,string) - handler: handleMarketRegistered + - event: MarketCreated(indexed uint128,string,string) + handler: handleMarketCreated + - event: MarketUpdated(uint128,uint256,int256,uint256,int256,int256,int256) + handler: handleMarketUpdated - event: MarketPriceDataUpdated(indexed uint128,bytes32) handler: handleMarketPriceDataUpdated - event: FundingParametersSet(indexed uint128,uint256,uint256) handler: handleFundingParametersSet - event: LiquidationParametersSet(indexed uint128,uint256,uint256,uint256,uint256,uint256,uint256) handler: handleLiquidationParametersSet - - event: LockedOiRatioD18Set(indexed uint128,uint256) - handler: handleLockedOiRatioD18Set + - event: LockedOiRatioSet(indexed uint128,uint256) + handler: handleLockedOiRatioSet - event: OrderFeesSet(indexed uint128,uint256,uint256) handler: handleOrderFeesSet - event: SettlementStrategyAdded(indexed uint128,(uint8,uint256,uint256,uint256,address,bytes32,string,uint256,uint256,bool),indexed uint256) @@ -39,5 +42,8 @@ dataSources: handler: handleSettlementStrategyEnabled - event: OrderCommitted(indexed uint128,indexed uint128,uint8,int128,uint256,uint256,uint256,indexed bytes32,address) handler: handleOrderCommitted - + - event: PositionLiquidated(indexed uint128,indexed uint128,uint256,int128) + handler: handlePositionLiquidated + - event: AccountLiquidated(indexed uint128,uint256,bool) + handler: handleAccountLiquidated file: ./src/core.ts diff --git a/protocol/synthetix/subgraph/generated/CoreProxy/CoreProxy.ts b/protocol/synthetix/subgraph/generated/CoreProxy/CoreProxy.ts index 2c5297168b..8aacea1100 100644 --- a/protocol/synthetix/subgraph/generated/CoreProxy/CoreProxy.ts +++ b/protocol/synthetix/subgraph/generated/CoreProxy/CoreProxy.ts @@ -1598,6 +1598,63 @@ export class CoreProxy__getMarketFeesResult { } } +export class CoreProxy__getMarketPoolDebtDistributionResult { + value0: BigInt; + value1: BigInt; + value2: BigInt; + + constructor(value0: BigInt, value1: BigInt, value2: BigInt) { + this.value0 = value0; + this.value1 = value1; + this.value2 = value2; + } + + toMap(): TypedMap { + let map = new TypedMap(); + map.set('value0', ethereum.Value.fromUnsignedBigInt(this.value0)); + map.set('value1', ethereum.Value.fromUnsignedBigInt(this.value1)); + map.set('value2', ethereum.Value.fromSignedBigInt(this.value2)); + return map; + } + + getSharesD18(): BigInt { + return this.value0; + } + + getTotalSharesD18(): BigInt { + return this.value1; + } + + getValuePerShareD27(): BigInt { + return this.value2; + } +} + +export class CoreProxy__getMarketPoolsResult { + value0: Array; + value1: Array; + + constructor(value0: Array, value1: Array) { + this.value0 = value0; + this.value1 = value1; + } + + toMap(): TypedMap { + let map = new TypedMap(); + map.set('value0', ethereum.Value.fromUnsignedBigIntArray(this.value0)); + map.set('value1', ethereum.Value.fromUnsignedBigIntArray(this.value1)); + return map; + } + + getInRangePoolIds(): Array { + return this.value0; + } + + getOutRangePoolIds(): Array { + return this.value1; + } +} + export class CoreProxy__getPoolConfigurationResultValue0Struct extends ethereum.Tuple { get marketId(): BigInt { return this[0].toBigInt(); @@ -2721,6 +2778,69 @@ export class CoreProxy extends ethereum.SmartContract { return ethereum.CallResult.fromValue(value[0].toBigInt()); } + getMarketPoolDebtDistribution( + marketId: BigInt, + poolId: BigInt + ): CoreProxy__getMarketPoolDebtDistributionResult { + let result = super.call( + 'getMarketPoolDebtDistribution', + 'getMarketPoolDebtDistribution(uint128,uint128):(uint256,uint128,int128)', + [ethereum.Value.fromUnsignedBigInt(marketId), ethereum.Value.fromUnsignedBigInt(poolId)] + ); + + return new CoreProxy__getMarketPoolDebtDistributionResult( + result[0].toBigInt(), + result[1].toBigInt(), + result[2].toBigInt() + ); + } + + try_getMarketPoolDebtDistribution( + marketId: BigInt, + poolId: BigInt + ): ethereum.CallResult { + let result = super.tryCall( + 'getMarketPoolDebtDistribution', + 'getMarketPoolDebtDistribution(uint128,uint128):(uint256,uint128,int128)', + [ethereum.Value.fromUnsignedBigInt(marketId), ethereum.Value.fromUnsignedBigInt(poolId)] + ); + if (result.reverted) { + return new ethereum.CallResult(); + } + let value = result.value; + return ethereum.CallResult.fromValue( + new CoreProxy__getMarketPoolDebtDistributionResult( + value[0].toBigInt(), + value[1].toBigInt(), + value[2].toBigInt() + ) + ); + } + + getMarketPools(marketId: BigInt): CoreProxy__getMarketPoolsResult { + let result = super.call('getMarketPools', 'getMarketPools(uint128):(uint128[],uint128[])', [ + ethereum.Value.fromUnsignedBigInt(marketId), + ]); + + return new CoreProxy__getMarketPoolsResult( + result[0].toBigIntArray(), + result[1].toBigIntArray() + ); + } + + try_getMarketPools(marketId: BigInt): ethereum.CallResult { + let result = super.tryCall('getMarketPools', 'getMarketPools(uint128):(uint128[],uint128[])', [ + ethereum.Value.fromUnsignedBigInt(marketId), + ]); + if (result.reverted) { + return new ethereum.CallResult(); + } + let value = result.value; + return ethereum.CallResult.fromValue( + new CoreProxy__getMarketPoolsResult(value[0].toBigIntArray(), value[1].toBigIntArray()) + ); + } + getMarketReportedDebt(marketId: BigInt): BigInt { let result = super.call('getMarketReportedDebt', 'getMarketReportedDebt(uint128):(uint256)', [ ethereum.Value.fromUnsignedBigInt(marketId), @@ -5038,6 +5158,90 @@ export class GetMarketDebtPerShareCall__Outputs { } } +export class GetMarketPoolDebtDistributionCall extends ethereum.Call { + get inputs(): GetMarketPoolDebtDistributionCall__Inputs { + return new GetMarketPoolDebtDistributionCall__Inputs(this); + } + + get outputs(): GetMarketPoolDebtDistributionCall__Outputs { + return new GetMarketPoolDebtDistributionCall__Outputs(this); + } +} + +export class GetMarketPoolDebtDistributionCall__Inputs { + _call: GetMarketPoolDebtDistributionCall; + + constructor(call: GetMarketPoolDebtDistributionCall) { + this._call = call; + } + + get marketId(): BigInt { + return this._call.inputValues[0].value.toBigInt(); + } + + get poolId(): BigInt { + return this._call.inputValues[1].value.toBigInt(); + } +} + +export class GetMarketPoolDebtDistributionCall__Outputs { + _call: GetMarketPoolDebtDistributionCall; + + constructor(call: GetMarketPoolDebtDistributionCall) { + this._call = call; + } + + get sharesD18(): BigInt { + return this._call.outputValues[0].value.toBigInt(); + } + + get totalSharesD18(): BigInt { + return this._call.outputValues[1].value.toBigInt(); + } + + get valuePerShareD27(): BigInt { + return this._call.outputValues[2].value.toBigInt(); + } +} + +export class GetMarketPoolsCall extends ethereum.Call { + get inputs(): GetMarketPoolsCall__Inputs { + return new GetMarketPoolsCall__Inputs(this); + } + + get outputs(): GetMarketPoolsCall__Outputs { + return new GetMarketPoolsCall__Outputs(this); + } +} + +export class GetMarketPoolsCall__Inputs { + _call: GetMarketPoolsCall; + + constructor(call: GetMarketPoolsCall) { + this._call = call; + } + + get marketId(): BigInt { + return this._call.inputValues[0].value.toBigInt(); + } +} + +export class GetMarketPoolsCall__Outputs { + _call: GetMarketPoolsCall; + + constructor(call: GetMarketPoolsCall) { + this._call = call; + } + + get inRangePoolIds(): Array { + return this._call.outputValues[0].value.toBigIntArray(); + } + + get outRangePoolIds(): Array { + return this._call.outputValues[1].value.toBigIntArray(); + } +} + export class RegisterMarketCall extends ethereum.Call { get inputs(): RegisterMarketCall__Inputs { return new RegisterMarketCall__Inputs(this); From 9a18e40644d912a2b7e9936967e85db804374cc2 Mon Sep 17 00:00:00 2001 From: Peiman Date: Mon, 7 Aug 2023 20:52:53 +0330 Subject: [PATCH 31/63] feat: update pool collateral configuration --- .../contracts/interfaces/IPoolModule.sol | 55 +++++-------------- .../contracts/modules/core/PoolModule.sol | 37 +++---------- .../modules/core/IssueUSDModule.test.ts | 5 +- .../modules/core/PoolModuleFundAdmin.test.ts | 22 ++++++-- .../modules/core/VaultModule.test.ts | 12 +++- .../storage/CollateralConfiguration.test.ts | 26 ++++++++- 6 files changed, 76 insertions(+), 81 deletions(-) diff --git a/protocol/synthetix/contracts/interfaces/IPoolModule.sol b/protocol/synthetix/contracts/interfaces/IPoolModule.sol index 360163fb93..dc4541dd9c 100644 --- a/protocol/synthetix/contracts/interfaces/IPoolModule.sol +++ b/protocol/synthetix/contracts/interfaces/IPoolModule.sol @@ -2,6 +2,7 @@ pragma solidity >=0.8.11 <0.9.0; import "../storage/MarketConfiguration.sol"; +import "../storage/PoolCollateralConfiguration.sol"; /** * @title Module for the creation and management of pools. @@ -74,32 +75,18 @@ interface IPoolModule { address indexed sender ); + event PoolCollateralConfigurationUpdated( + uint128 indexed poolId, + address collateralType, + PoolCollateralConfiguration.Data config + ); + /** * @notice Emitted when a system-wide minimum liquidity ratio is set * @param minLiquidityRatio The new system-wide minimum liquidity ratio */ event SetMinLiquidityRatio(uint256 minLiquidityRatio); - /** - * @notice Gets fired when pool collateral is enabled. - * @param poolId The id of the pool for which the collateral is being enabled. - * @param collateral The address of the collateral. - * @param sender The address that triggered the action. - */ - event PoolCollateralEnabled(uint128 indexed poolId, address collateral, address indexed sender); - - /** - * @notice Gets fired when pool collateral is disabled. - * @param poolId The id of the pool for which the collateral is being disabled. - * @param collateral The address of the collateral. - * @param sender The address that triggered the action. - */ - event PoolCollateralDisabled( - uint128 indexed poolId, - address collateral, - address indexed sender - ); - /** * @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. @@ -187,20 +174,6 @@ interface IPoolModule { */ function setMinLiquidityRatio(uint256 minLiquidityRatio) external; - /** - * @notice Gets fired when a pool collateral is disabled for a pool. - * @param poolId The id of the pool for which the collateral is being disabled. - * @param collateral The address of the collateral. - */ - function disablePoolCollateralDelegation(uint128 poolId, address collateral) external; - - /** - * @notice Gets fired when a collateral is enabled for a pool. - * @param poolId The id of the pool for which the collateral is being enabled. - * @param collateral The address of the collateral. - */ - function enablePoolCollateralDelegation(uint128 poolId, address collateral) 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. @@ -212,15 +185,15 @@ interface IPoolModule { ) external view returns (bool enabled); /** - @notice sets a pool minimum issuance ratio - * @param poolId The id of the pool for to check the collateral for. - * @param collateral The address of the collateral. - * @param issuanceRatioD18 The minimum issuance ratio denominated with 18 decimal places + * @notice Allows the pool owner to set the configuration of a specific collateral type for their pool. + * @param poolId The id of the pool whose configuration is being set. + * @param collateralType The collate + * @param newConfig The config to set */ - function setPoolCollateralIssuanceRatio( + function setPoolCollateralConfiguration( uint128 poolId, - address collateral, - uint256 issuanceRatioD18 + address collateralType, + PoolCollateralConfiguration.Data memory newConfig ) external; /** diff --git a/protocol/synthetix/contracts/modules/core/PoolModule.sol b/protocol/synthetix/contracts/modules/core/PoolModule.sol index a4861916ce..f2066b75a4 100644 --- a/protocol/synthetix/contracts/modules/core/PoolModule.sol +++ b/protocol/synthetix/contracts/modules/core/PoolModule.sol @@ -228,30 +228,6 @@ contract PoolModule is IPoolModule { emit PoolNameUpdated(poolId, name, msg.sender); } - /** - * @inheritdoc IPoolModule - */ - function enablePoolCollateralDelegation(uint128 poolId, address collateral) external override { - Pool.Data storage pool = Pool.loadExisting(poolId); - Pool.onlyPoolOwner(poolId, msg.sender); - - pool.collateralConfigurations[collateral].collateralTypeDisabled = false; - - emit PoolCollateralEnabled(poolId, collateral, msg.sender); - } - - /** - * @inheritdoc IPoolModule - */ - function disablePoolCollateralDelegation(uint128 poolId, address collateral) external override { - Pool.Data storage pool = Pool.loadExisting(poolId); - Pool.onlyPoolOwner(poolId, msg.sender); - - pool.collateralConfigurations[collateral].collateralTypeDisabled = true; - - emit PoolCollateralDisabled(poolId, collateral, msg.sender); - } - /** * @inheritdoc IPoolModule */ @@ -259,23 +235,24 @@ contract PoolModule is IPoolModule { uint128 poolId, address collateral ) external view override returns (bool) { - return !Pool.load(poolId).collateralConfigurations[collateral].collateralTypeDisabled; + return + !Pool.loadExisting(poolId).collateralConfigurations[collateral].collateralTypeDisabled; } /** * @inheritdoc IPoolModule */ - function setPoolCollateralIssuanceRatio( + function setPoolCollateralConfiguration( uint128 poolId, - address collateral, - uint256 issuanceRatioD18 + address collateralType, + PoolCollateralConfiguration.Data memory newConfig ) external override { Pool.Data storage pool = Pool.loadExisting(poolId); Pool.onlyPoolOwner(poolId, msg.sender); - pool.collateralConfigurations[collateral].issuanceRatioD18 = issuanceRatioD18; + pool.collateralConfigurations[collateralType] = newConfig; - emit PoolCollateralDisabled(poolId, collateral, msg.sender); + emit PoolCollateralConfigurationUpdated(poolId, collateralType, newConfig); } /** diff --git a/protocol/synthetix/test/integration/modules/core/IssueUSDModule.test.ts b/protocol/synthetix/test/integration/modules/core/IssueUSDModule.test.ts index 0d47b46ec3..6e3967c719 100644 --- a/protocol/synthetix/test/integration/modules/core/IssueUSDModule.test.ts +++ b/protocol/synthetix/test/integration/modules/core/IssueUSDModule.test.ts @@ -450,7 +450,10 @@ describe('IssueUSDModule', function () { it('set the pool min collateal issuance ratio to 600%', async () => { await systems() .Core.connect(owner) - .setPoolCollateralIssuanceRatio(poolId, collateralAddress(), bn(6)); + .setPoolCollateralConfiguration(poolId, collateralAddress(), { + collateralTypeDisabled: false, + issuanceRatioD18: bn(6), + }); }); it('verifies sufficient c-ratio', async () => { diff --git a/protocol/synthetix/test/integration/modules/core/PoolModuleFundAdmin.test.ts b/protocol/synthetix/test/integration/modules/core/PoolModuleFundAdmin.test.ts index 42290551aa..85da4467e0 100644 --- a/protocol/synthetix/test/integration/modules/core/PoolModuleFundAdmin.test.ts +++ b/protocol/synthetix/test/integration/modules/core/PoolModuleFundAdmin.test.ts @@ -709,7 +709,10 @@ describe('PoolModule Admin', function () { await assertRevert( systems() .Core.connect(user2) - .enablePoolCollateralDelegation(thirdPoolId, collateralAddress()), + .setPoolCollateralConfiguration(thirdPoolId, collateralAddress(), { + collateralTypeDisabled: false, + issuanceRatioD18: bn(0), + }), `Unauthorized("${await user2.getAddress()}")`, systems().Core ); @@ -725,7 +728,10 @@ describe('PoolModule Admin', function () { it('disable the collateral by pool owner', async () => { await systems() .Core.connect(user1) - .disablePoolCollateralDelegation(thirdPoolId, collateralAddress()); + .setPoolCollateralConfiguration(thirdPoolId, collateralAddress(), { + collateralTypeDisabled: false, + issuanceRatioD18: bn(2), + }); }); it('collateral is disabled for the pool', async () => { @@ -736,7 +742,7 @@ describe('PoolModule Admin', function () { }); }); - describe('setPoolCollateralIssuanceRatio()', async () => { + describe('set pool collateral issuance ratio', async () => { before(restore); before('give user1 permission to create pool', async () => { @@ -760,7 +766,10 @@ describe('PoolModule Admin', function () { await assertRevert( systems() .Core.connect(user2) - .setPoolCollateralIssuanceRatio(thirdPoolId, collateralAddress(), bn(2)), + .setPoolCollateralConfiguration(thirdPoolId, collateralAddress(), { + collateralTypeDisabled: false, + issuanceRatioD18: bn(2), + }), `Unauthorized("${await user2.getAddress()}")`, systems().Core ); @@ -776,7 +785,10 @@ describe('PoolModule Admin', function () { it('set the pool collateal issuance ratio to 200%', async () => { await systems() .Core.connect(user1) - .setPoolCollateralIssuanceRatio(thirdPoolId, collateralAddress(), bn(2)); + .setPoolCollateralConfiguration(thirdPoolId, collateralAddress(), { + collateralTypeDisabled: false, + issuanceRatioD18: bn(2), + }); await assertBn.equal( await systems().Core.getPoolCollateralIssuanceRatio(thirdPoolId, collateralAddress()), diff --git a/protocol/synthetix/test/integration/modules/core/VaultModule.test.ts b/protocol/synthetix/test/integration/modules/core/VaultModule.test.ts index 3fc1d3a5a9..23a88bbd90 100644 --- a/protocol/synthetix/test/integration/modules/core/VaultModule.test.ts +++ b/protocol/synthetix/test/integration/modules/core/VaultModule.test.ts @@ -4,7 +4,7 @@ import { snapshotCheckpoint } from '@synthetixio/core-utils/utils/mocha/snapshot import assert from 'assert/strict'; import { BigNumber, ethers } from 'ethers'; import hre from 'hardhat'; -import { bootstrapWithStakedPool } from '../../bootstrap'; +import { bn, bootstrapWithStakedPool } from '../../bootstrap'; import Permissions from '../../mixins/AccountRBACMixin.permissions'; import { verifyUsesFeatureFlag } from '../../verifications'; import { fastForwardTo, getTime } from '@synthetixio/core-utils/utils/hardhat/rpc'; @@ -338,7 +338,10 @@ describe('VaultModule', function () { before('disable collateral for the pool by the pool owner', async () => { await systems() .Core.connect(user1) - .disablePoolCollateralDelegation(fakeVaultId, collateralAddress()); + .setPoolCollateralConfiguration(fakeVaultId, collateralAddress(), { + collateralTypeDisabled: true, + issuanceRatioD18: bn(0), + }); }); // fails when collateral is disabled for the pool by pool owner @@ -361,7 +364,10 @@ describe('VaultModule', function () { it('collateral is enabled by the pool owner', async () => { await systems() .Core.connect(user1) - .enablePoolCollateralDelegation(fakeVaultId, collateralAddress()); + .setPoolCollateralConfiguration(fakeVaultId, collateralAddress(), { + collateralTypeDisabled: false, + issuanceRatioD18: bn(0), + }); }); it('the delegation works as expected with the enabled collateral', async () => { diff --git a/protocol/synthetix/test/integration/storage/CollateralConfiguration.test.ts b/protocol/synthetix/test/integration/storage/CollateralConfiguration.test.ts index 3e58dd5a08..9473296ac6 100644 --- a/protocol/synthetix/test/integration/storage/CollateralConfiguration.test.ts +++ b/protocol/synthetix/test/integration/storage/CollateralConfiguration.test.ts @@ -5,7 +5,7 @@ import { bootstrap } from '../bootstrap'; import { ethers } from 'ethers'; import hre from 'hardhat'; -describe('CollateralConfiguration', function () { +describe.only('CollateralConfiguration', function () { const { systems, signers } = bootstrap(); let owner: ethers.Signer; @@ -54,6 +54,30 @@ describe('CollateralConfiguration', function () { 'InsufficientCollateralRatio("499", "100", "4990000000000000000", "5000000000000000000")', systems().Core ); + + // default to system issuanceRatioD18 + await assertRevert( + systems().Core.CollateralConfiguration_verifyIssuanceRatio( + fakeCollateral.address, + 100, + 499, + ONE.mul(3) + ), + 'InsufficientCollateralRatio("499", "100", "4990000000000000000", "5000000000000000000")', + systems().Core + ); + + // override with minIssuanceRatioD18 + await assertRevert( + systems().Core.CollateralConfiguration_verifyIssuanceRatio( + fakeCollateral.address, + 100, + 500, + ONE.mul(6) + ), + 'InsufficientCollateralRatio("500", "100", "5000000000000000000", "6000000000000000000")', + systems().Core + ); }); it('succeeds when c-ratio is good', async () => { From 46fc2ec26858de7fcf20ffa8b486dddbf8f7df86 Mon Sep 17 00:00:00 2001 From: Peiman Date: Mon, 7 Aug 2023 21:01:26 +0330 Subject: [PATCH 32/63] fix: liniting --- .../test/integration/storage/CollateralConfiguration.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/protocol/synthetix/test/integration/storage/CollateralConfiguration.test.ts b/protocol/synthetix/test/integration/storage/CollateralConfiguration.test.ts index 9473296ac6..e01643c6fd 100644 --- a/protocol/synthetix/test/integration/storage/CollateralConfiguration.test.ts +++ b/protocol/synthetix/test/integration/storage/CollateralConfiguration.test.ts @@ -5,7 +5,7 @@ import { bootstrap } from '../bootstrap'; import { ethers } from 'ethers'; import hre from 'hardhat'; -describe.only('CollateralConfiguration', function () { +describe('CollateralConfiguration', function () { const { systems, signers } = bootstrap(); let owner: ethers.Signer; From 7e175fe6b1ead0aeb49031eeb6a37dd68e4e2bfd Mon Sep 17 00:00:00 2001 From: "troy (troyb.eth)" Date: Mon, 7 Aug 2023 12:49:35 -0600 Subject: [PATCH 33/63] Update perps subgraph (#1748) * update subgraph * add timestamps * fix order ids * update graph * fix deploy * remove size * update deployment location * remove yaml diff * Update markets/perps-market/subgraph/src/market.ts Co-authored-by: Noisekit --------- Co-authored-by: Noisekit --- .../perps-market/subgraph/generated/schema.ts | 520 +++++++++++++++++- markets/perps-market/subgraph/schema.graphql | 45 +- markets/perps-market/subgraph/src/market.ts | 28 +- markets/perps-market/subgraph/src/orders.ts | 85 ++- .../subgraph/src/settlementStrategies.ts | 1 + .../perps-market/subgraph/subgraph.base.yaml | 5 + 6 files changed, 667 insertions(+), 17 deletions(-) diff --git a/markets/perps-market/subgraph/generated/schema.ts b/markets/perps-market/subgraph/generated/schema.ts index c28cc20c9a..c4163895a0 100644 --- a/markets/perps-market/subgraph/generated/schema.ts +++ b/markets/perps-market/subgraph/generated/schema.ts @@ -977,8 +977,8 @@ export class Order extends Entity { } } - get settelementReward(): BigInt | null { - let value = this.get('settelementReward'); + get settlementReward(): BigInt | null { + let value = this.get('settlementReward'); if (!value || value.kind == ValueKind.NULL) { return null; } else { @@ -986,11 +986,11 @@ export class Order extends Entity { } } - set settelementReward(value: BigInt | null) { + set settlementReward(value: BigInt | null) { if (!value) { - this.unset('settelementReward'); + this.unset('settlementReward'); } else { - this.set('settelementReward', Value.fromBigInt(value)); + this.set('settlementReward', Value.fromBigInt(value)); } } @@ -1413,3 +1413,513 @@ export class GlobalConfiguration extends Entity { } } } + +export class OrderCommitted extends Entity { + constructor(id: string) { + super(); + this.set('id', Value.fromString(id)); + } + + save(): void { + let id = this.get('id'); + assert(id != null, 'Cannot save OrderCommitted entity without an ID'); + if (id) { + assert( + id.kind == ValueKind.STRING, + `Entities of type OrderCommitted must have an ID of type String but the id '${id.displayData()}' is of type ${id.displayKind()}` + ); + store.set('OrderCommitted', id.toString(), this); + } + } + + static loadInBlock(id: string): OrderCommitted | null { + return changetype(store.get_in_block('OrderCommitted', id)); + } + + static load(id: string): OrderCommitted | null { + return changetype(store.get('OrderCommitted', id)); + } + + get id(): string { + let value = this.get('id'); + if (!value || value.kind == ValueKind.NULL) { + throw new Error('Cannot return null for a required field.'); + } else { + return value.toString(); + } + } + + set id(value: string) { + this.set('id', Value.fromString(value)); + } + + get timestamp(): BigInt { + let value = this.get('timestamp'); + if (!value || value.kind == ValueKind.NULL) { + throw new Error('Cannot return null for a required field.'); + } else { + return value.toBigInt(); + } + } + + set timestamp(value: BigInt) { + this.set('timestamp', Value.fromBigInt(value)); + } + + get marketId(): BigInt { + let value = this.get('marketId'); + if (!value || value.kind == ValueKind.NULL) { + throw new Error('Cannot return null for a required field.'); + } else { + return value.toBigInt(); + } + } + + set marketId(value: BigInt) { + this.set('marketId', Value.fromBigInt(value)); + } + + get accountId(): BigInt { + let value = this.get('accountId'); + if (!value || value.kind == ValueKind.NULL) { + throw new Error('Cannot return null for a required field.'); + } else { + return value.toBigInt(); + } + } + + set accountId(value: BigInt) { + this.set('accountId', Value.fromBigInt(value)); + } + + get orderType(): i32 { + let value = this.get('orderType'); + if (!value || value.kind == ValueKind.NULL) { + return 0; + } else { + return value.toI32(); + } + } + + set orderType(value: i32) { + this.set('orderType', Value.fromI32(value)); + } + + get sizeDelta(): BigInt { + let value = this.get('sizeDelta'); + if (!value || value.kind == ValueKind.NULL) { + throw new Error('Cannot return null for a required field.'); + } else { + return value.toBigInt(); + } + } + + set sizeDelta(value: BigInt) { + this.set('sizeDelta', Value.fromBigInt(value)); + } + + get acceptablePrice(): BigInt { + let value = this.get('acceptablePrice'); + if (!value || value.kind == ValueKind.NULL) { + throw new Error('Cannot return null for a required field.'); + } else { + return value.toBigInt(); + } + } + + set acceptablePrice(value: BigInt) { + this.set('acceptablePrice', Value.fromBigInt(value)); + } + + get settlementTime(): BigInt { + let value = this.get('settlementTime'); + if (!value || value.kind == ValueKind.NULL) { + throw new Error('Cannot return null for a required field.'); + } else { + return value.toBigInt(); + } + } + + set settlementTime(value: BigInt) { + this.set('settlementTime', Value.fromBigInt(value)); + } + + get expirationTime(): BigInt { + let value = this.get('expirationTime'); + if (!value || value.kind == ValueKind.NULL) { + throw new Error('Cannot return null for a required field.'); + } else { + return value.toBigInt(); + } + } + + set expirationTime(value: BigInt) { + this.set('expirationTime', Value.fromBigInt(value)); + } + + get trackingCode(): Bytes { + let value = this.get('trackingCode'); + if (!value || value.kind == ValueKind.NULL) { + throw new Error('Cannot return null for a required field.'); + } else { + return value.toBytes(); + } + } + + set trackingCode(value: Bytes) { + this.set('trackingCode', Value.fromBytes(value)); + } + + get sender(): Bytes { + let value = this.get('sender'); + if (!value || value.kind == ValueKind.NULL) { + throw new Error('Cannot return null for a required field.'); + } else { + return value.toBytes(); + } + } + + set sender(value: Bytes) { + this.set('sender', Value.fromBytes(value)); + } +} + +export class OrderSettled extends Entity { + constructor(id: string) { + super(); + this.set('id', Value.fromString(id)); + } + + save(): void { + let id = this.get('id'); + assert(id != null, 'Cannot save OrderSettled entity without an ID'); + if (id) { + assert( + id.kind == ValueKind.STRING, + `Entities of type OrderSettled must have an ID of type String but the id '${id.displayData()}' is of type ${id.displayKind()}` + ); + store.set('OrderSettled', id.toString(), this); + } + } + + static loadInBlock(id: string): OrderSettled | null { + return changetype(store.get_in_block('OrderSettled', id)); + } + + static load(id: string): OrderSettled | null { + return changetype(store.get('OrderSettled', id)); + } + + get id(): string { + let value = this.get('id'); + if (!value || value.kind == ValueKind.NULL) { + throw new Error('Cannot return null for a required field.'); + } else { + return value.toString(); + } + } + + set id(value: string) { + this.set('id', Value.fromString(value)); + } + + get timestamp(): BigInt { + let value = this.get('timestamp'); + if (!value || value.kind == ValueKind.NULL) { + throw new Error('Cannot return null for a required field.'); + } else { + return value.toBigInt(); + } + } + + set timestamp(value: BigInt) { + this.set('timestamp', Value.fromBigInt(value)); + } + + get marketId(): BigInt { + let value = this.get('marketId'); + if (!value || value.kind == ValueKind.NULL) { + throw new Error('Cannot return null for a required field.'); + } else { + return value.toBigInt(); + } + } + + set marketId(value: BigInt) { + this.set('marketId', Value.fromBigInt(value)); + } + + get accountId(): BigInt { + let value = this.get('accountId'); + if (!value || value.kind == ValueKind.NULL) { + throw new Error('Cannot return null for a required field.'); + } else { + return value.toBigInt(); + } + } + + set accountId(value: BigInt) { + this.set('accountId', Value.fromBigInt(value)); + } + + get fillPrice(): BigInt { + let value = this.get('fillPrice'); + if (!value || value.kind == ValueKind.NULL) { + throw new Error('Cannot return null for a required field.'); + } else { + return value.toBigInt(); + } + } + + set fillPrice(value: BigInt) { + this.set('fillPrice', Value.fromBigInt(value)); + } + + get sizeDelta(): BigInt { + let value = this.get('sizeDelta'); + if (!value || value.kind == ValueKind.NULL) { + throw new Error('Cannot return null for a required field.'); + } else { + return value.toBigInt(); + } + } + + set sizeDelta(value: BigInt) { + this.set('sizeDelta', Value.fromBigInt(value)); + } + + get newSize(): BigInt { + let value = this.get('newSize'); + if (!value || value.kind == ValueKind.NULL) { + throw new Error('Cannot return null for a required field.'); + } else { + return value.toBigInt(); + } + } + + set newSize(value: BigInt) { + this.set('newSize', Value.fromBigInt(value)); + } + + get totalFees(): BigInt { + let value = this.get('totalFees'); + if (!value || value.kind == ValueKind.NULL) { + throw new Error('Cannot return null for a required field.'); + } else { + return value.toBigInt(); + } + } + + set totalFees(value: BigInt) { + this.set('totalFees', Value.fromBigInt(value)); + } + + get referralFees(): BigInt { + let value = this.get('referralFees'); + if (!value || value.kind == ValueKind.NULL) { + throw new Error('Cannot return null for a required field.'); + } else { + return value.toBigInt(); + } + } + + set referralFees(value: BigInt) { + this.set('referralFees', Value.fromBigInt(value)); + } + + get collectedFees(): BigInt { + let value = this.get('collectedFees'); + if (!value || value.kind == ValueKind.NULL) { + throw new Error('Cannot return null for a required field.'); + } else { + return value.toBigInt(); + } + } + + set collectedFees(value: BigInt) { + this.set('collectedFees', Value.fromBigInt(value)); + } + + get settlementReward(): BigInt { + let value = this.get('settlementReward'); + if (!value || value.kind == ValueKind.NULL) { + throw new Error('Cannot return null for a required field.'); + } else { + return value.toBigInt(); + } + } + + set settlementReward(value: BigInt) { + this.set('settlementReward', Value.fromBigInt(value)); + } + + get trackingCode(): Bytes { + let value = this.get('trackingCode'); + if (!value || value.kind == ValueKind.NULL) { + throw new Error('Cannot return null for a required field.'); + } else { + return value.toBytes(); + } + } + + set trackingCode(value: Bytes) { + this.set('trackingCode', Value.fromBytes(value)); + } + + get settler(): Bytes { + let value = this.get('settler'); + if (!value || value.kind == ValueKind.NULL) { + throw new Error('Cannot return null for a required field.'); + } else { + return value.toBytes(); + } + } + + set settler(value: Bytes) { + this.set('settler', Value.fromBytes(value)); + } +} + +export class MarketUpdated extends Entity { + constructor(id: string) { + super(); + this.set('id', Value.fromString(id)); + } + + save(): void { + let id = this.get('id'); + assert(id != null, 'Cannot save MarketUpdated entity without an ID'); + if (id) { + assert( + id.kind == ValueKind.STRING, + `Entities of type MarketUpdated must have an ID of type String but the id '${id.displayData()}' is of type ${id.displayKind()}` + ); + store.set('MarketUpdated', id.toString(), this); + } + } + + static loadInBlock(id: string): MarketUpdated | null { + return changetype(store.get_in_block('MarketUpdated', id)); + } + + static load(id: string): MarketUpdated | null { + return changetype(store.get('MarketUpdated', id)); + } + + get id(): string { + let value = this.get('id'); + if (!value || value.kind == ValueKind.NULL) { + throw new Error('Cannot return null for a required field.'); + } else { + return value.toString(); + } + } + + set id(value: string) { + this.set('id', Value.fromString(value)); + } + + get timestamp(): BigInt { + let value = this.get('timestamp'); + if (!value || value.kind == ValueKind.NULL) { + throw new Error('Cannot return null for a required field.'); + } else { + return value.toBigInt(); + } + } + + set timestamp(value: BigInt) { + this.set('timestamp', Value.fromBigInt(value)); + } + + get marketId(): BigInt { + let value = this.get('marketId'); + if (!value || value.kind == ValueKind.NULL) { + throw new Error('Cannot return null for a required field.'); + } else { + return value.toBigInt(); + } + } + + set marketId(value: BigInt) { + this.set('marketId', Value.fromBigInt(value)); + } + + get price(): BigInt { + let value = this.get('price'); + if (!value || value.kind == ValueKind.NULL) { + throw new Error('Cannot return null for a required field.'); + } else { + return value.toBigInt(); + } + } + + set price(value: BigInt) { + this.set('price', Value.fromBigInt(value)); + } + + get skew(): BigInt { + let value = this.get('skew'); + if (!value || value.kind == ValueKind.NULL) { + throw new Error('Cannot return null for a required field.'); + } else { + return value.toBigInt(); + } + } + + set skew(value: BigInt) { + this.set('skew', Value.fromBigInt(value)); + } + + get size(): BigInt { + let value = this.get('size'); + if (!value || value.kind == ValueKind.NULL) { + throw new Error('Cannot return null for a required field.'); + } else { + return value.toBigInt(); + } + } + + set size(value: BigInt) { + this.set('size', Value.fromBigInt(value)); + } + + get sizeDelta(): BigInt { + let value = this.get('sizeDelta'); + if (!value || value.kind == ValueKind.NULL) { + throw new Error('Cannot return null for a required field.'); + } else { + return value.toBigInt(); + } + } + + set sizeDelta(value: BigInt) { + this.set('sizeDelta', Value.fromBigInt(value)); + } + + get currentFundingRate(): BigInt { + let value = this.get('currentFundingRate'); + if (!value || value.kind == ValueKind.NULL) { + throw new Error('Cannot return null for a required field.'); + } else { + return value.toBigInt(); + } + } + + set currentFundingRate(value: BigInt) { + this.set('currentFundingRate', Value.fromBigInt(value)); + } + + get currentFundingVelocity(): BigInt { + let value = this.get('currentFundingVelocity'); + if (!value || value.kind == ValueKind.NULL) { + throw new Error('Cannot return null for a required field.'); + } else { + return value.toBigInt(); + } + } + + set currentFundingVelocity(value: BigInt) { + this.set('currentFundingVelocity', Value.fromBigInt(value)); + } +} diff --git a/markets/perps-market/subgraph/schema.graphql b/markets/perps-market/subgraph/schema.graphql index 918eada1b7..8c8c6511c6 100644 --- a/markets/perps-market/subgraph/schema.graphql +++ b/markets/perps-market/subgraph/schema.graphql @@ -65,7 +65,7 @@ type Order @entity { accountPnlRealized: BigInt newSize: BigInt collectedFees: BigInt - settelementReward: BigInt + settlementReward: BigInt settler: String block: BigInt! @@ -99,3 +99,46 @@ type GlobalConfiguration @entity { id: ID! feeCollector: String } + +# raw events +type OrderCommitted @entity { + id: ID! + timestamp: BigInt! + marketId: BigInt! + accountId: BigInt! + orderType: Int! + sizeDelta: BigInt! + acceptablePrice: BigInt! + settlementTime: BigInt! + expirationTime: BigInt! + trackingCode: Bytes! + sender: Bytes! +} + +type OrderSettled @entity { + id: ID! + timestamp: BigInt! + marketId: BigInt! + accountId: BigInt! + fillPrice: BigInt! + sizeDelta: BigInt! + newSize: BigInt! + totalFees: BigInt! + referralFees: BigInt! + collectedFees: BigInt! + settlementReward: BigInt! + trackingCode: Bytes! + settler: Bytes! +} + +type MarketUpdated @entity { + id: ID! + timestamp: BigInt! + marketId: BigInt! + price: BigInt! + skew: BigInt! + size: BigInt! + sizeDelta: BigInt! + currentFundingRate: BigInt! + currentFundingVelocity: BigInt! +} diff --git a/markets/perps-market/subgraph/src/market.ts b/markets/perps-market/subgraph/src/market.ts index cf5e23d455..f86596e06b 100644 --- a/markets/perps-market/subgraph/src/market.ts +++ b/markets/perps-market/subgraph/src/market.ts @@ -5,11 +5,11 @@ import { LiquidationParametersSet, LockedOiRatioSet, OrderFeesSet, - MarketUpdated, + MarketUpdated as MarketUpdatedEvent, FactoryInitialized, } from '../generated/PerpsMarketProxy/PerpsMarketProxy'; -import { Market } from '../generated/schema'; +import { Market, MarketUpdated } from '../generated/schema'; export function handleMarketCreated(event: MarketCreated): void { const id = event.params.perpsMarketId.toString(); @@ -21,7 +21,7 @@ export function handleMarketCreated(event: MarketCreated): void { market.save(); } -export function handleMarketUpdated(event: MarketUpdated): void { +export function handleMarketUpdated(event: MarketUpdatedEvent): void { const id = event.params.marketId.toString(); const market = new Market(id); @@ -31,7 +31,29 @@ export function handleMarketUpdated(event: MarketUpdated): void { market.sizeDelta = event.params.sizeDelta; market.currentFundingRate = event.params.currentFundingRate; market.currentFundingVelocity = event.params.currentFundingVelocity; + market.save(); + + // create MarketUpdated entity + const marketUpdatedId = + event.params.marketId.toString() + + '-' + + event.block.number.toString() + + '-' + + event.logIndex.toString(); + + let marketUpdated = new MarketUpdated(marketUpdatedId); + + marketUpdated.timestamp = event.block.timestamp; + marketUpdated.marketId = event.params.marketId; + marketUpdated.price = event.params.price; + marketUpdated.skew = event.params.skew; + marketUpdated.size = event.params.size; + marketUpdated.sizeDelta = event.params.sizeDelta; + marketUpdated.currentFundingRate = event.params.currentFundingRate; + marketUpdated.currentFundingVelocity = event.params.currentFundingVelocity; + + marketUpdated.save(); } export function handleMarketPriceDataUpdated(event: MarketPriceDataUpdated): void { diff --git a/markets/perps-market/subgraph/src/orders.ts b/markets/perps-market/subgraph/src/orders.ts index ea6855da63..ee32a54921 100644 --- a/markets/perps-market/subgraph/src/orders.ts +++ b/markets/perps-market/subgraph/src/orders.ts @@ -1,22 +1,26 @@ -import { OrderCommitted } from '../generated/PerpsMarketProxy/PerpsMarketProxy'; +import { + OrderCommitted as OrderCommittedEvent, + OrderSettled as OrderSettledEvent, + MarketUpdated as MarketUpdatedEvent, +} from '../generated/PerpsMarketProxy/PerpsMarketProxy'; import { BigInt } from '@graphprotocol/graph-ts'; import { ZERO_BI } from './helpers'; -import { Order } from '../generated/schema'; +import { Order, OrderCommitted, OrderSettled, MarketUpdated } from '../generated/schema'; -export function handleOrderCommitted(event: OrderCommitted): void { - const id = - event.params.sender.toHexString() + - '-' + +export function handleOrderCommitted(event: OrderCommittedEvent): void { + const orderId = event.params.marketId.toString() + '-' + event.params.accountId.toString(); + const orderCommittedId = event.params.marketId.toString() + '-' + event.params.accountId.toString() + '-' + event.block.number.toString(); - let order = Order.load(id); + // create Order entity + let order = Order.load(orderId); if (!order) { - order = new Order(id); + order = new Order(orderId); order.size = ZERO_BI; } @@ -34,4 +38,69 @@ export function handleOrderCommitted(event: OrderCommitted): void { order.timestamp = event.block.timestamp; order.save(); + + // create OrderCommitted entity + let orderCommitted = new OrderCommitted(orderCommittedId); + + orderCommitted.timestamp = event.block.timestamp; + orderCommitted.marketId = event.params.marketId; + orderCommitted.accountId = event.params.accountId; + orderCommitted.orderType = event.params.orderType; + orderCommitted.sizeDelta = event.params.sizeDelta; + orderCommitted.acceptablePrice = event.params.acceptablePrice; + orderCommitted.settlementTime = event.params.settlementTime; + orderCommitted.expirationTime = event.params.expirationTime; + orderCommitted.trackingCode = event.params.trackingCode; + orderCommitted.sender = event.params.sender; + + orderCommitted.save(); +} + +export function handleOrderSettled(event: OrderSettledEvent): void { + const orderId = event.params.marketId.toString() + '-' + event.params.accountId.toString(); + const orderSettledId = + event.params.marketId.toString() + + '-' + + event.params.accountId.toString() + + '-' + + event.block.number.toString(); + + // update Order entity + let order = Order.load(orderId); + + if (!order) { + order = new Order(orderId); + order.size = ZERO_BI; + order.newSize = ZERO_BI; + } + + order.marketId = event.params.marketId; + order.accountId = event.params.accountId; + order.newSize = event.params.newSize; + order.fillPrice = event.params.fillPrice; + order.settlementReward = event.params.settlementReward; + order.collectedFees = event.params.collectedFees; + order.settler = event.params.settler.toHexString(); + + order.block = event.block.number; + order.timestamp = event.block.timestamp; + + order.save(); + + // create OrderSettled entity + let orderSettled = new OrderSettled(orderSettledId); + orderSettled.timestamp = event.block.timestamp; + orderSettled.marketId = event.params.marketId; + orderSettled.accountId = event.params.accountId; + orderSettled.fillPrice = event.params.fillPrice; + orderSettled.sizeDelta = event.params.sizeDelta; + orderSettled.newSize = event.params.newSize; + orderSettled.totalFees = event.params.totalFees; + orderSettled.referralFees = event.params.referralFees; + orderSettled.collectedFees = event.params.collectedFees; + orderSettled.settlementReward = event.params.settlementReward; + orderSettled.trackingCode = event.params.trackingCode; + orderSettled.settler = event.params.settler; + + orderSettled.save(); } diff --git a/markets/perps-market/subgraph/src/settlementStrategies.ts b/markets/perps-market/subgraph/src/settlementStrategies.ts index 6a0a51011b..98abfe356d 100644 --- a/markets/perps-market/subgraph/src/settlementStrategies.ts +++ b/markets/perps-market/subgraph/src/settlementStrategies.ts @@ -21,6 +21,7 @@ export function handleSettlementStrategyAdded(event: SettlementStrategyAdded): v strategy.url = event.params.strategy.url; strategy.settlementReward = event.params.strategy.settlementReward; strategy.priceDeviationTolerance = event.params.strategy.priceDeviationTolerance; + strategy.enabled = !event.params.strategy.disabled; strategy.save(); } diff --git a/markets/perps-market/subgraph/subgraph.base.yaml b/markets/perps-market/subgraph/subgraph.base.yaml index d7562dae63..9a0d49e07a 100644 --- a/markets/perps-market/subgraph/subgraph.base.yaml +++ b/markets/perps-market/subgraph/subgraph.base.yaml @@ -19,6 +19,9 @@ dataSources: - Market - Order - SettlementStrategy + - OrderCommitted + - OrderSettled + - MarketUpdated eventHandlers: - event: AccountCreated(indexed uint128,indexed address) handler: handleAccountCreated @@ -42,6 +45,8 @@ dataSources: handler: handleSettlementStrategyEnabled - event: OrderCommitted(indexed uint128,indexed uint128,uint8,int128,uint256,uint256,uint256,indexed bytes32,address) handler: handleOrderCommitted + - event: OrderSettled(indexed uint128,indexed uint128,uint256,int256,int128,int128,uint256,uint256,uint256,uint256,indexed bytes32,address) + handler: handleOrderSettled - event: PositionLiquidated(indexed uint128,indexed uint128,uint256,int128) handler: handlePositionLiquidated - event: AccountLiquidated(indexed uint128,uint256,bool) From 3db1995599c4383d31c9a37dd4f59c0692b90c95 Mon Sep 17 00:00:00 2001 From: Daniel Beal Date: Mon, 7 Aug 2023 12:34:18 -0700 Subject: [PATCH 34/63] fixes for audit * fix typo in external node definition * emit parameter error when bytes32 arrays dont match up --- .../contracts/interfaces/external/IExternalNode.sol | 2 +- protocol/oracle-manager/contracts/modules/NodeModule.sol | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/protocol/oracle-manager/contracts/interfaces/external/IExternalNode.sol b/protocol/oracle-manager/contracts/interfaces/external/IExternalNode.sol index a99e528713..275a629d15 100644 --- a/protocol/oracle-manager/contracts/interfaces/external/IExternalNode.sol +++ b/protocol/oracle-manager/contracts/interfaces/external/IExternalNode.sol @@ -12,7 +12,7 @@ interface IExternalNode is IERC165 { NodeOutput.Data[] memory parentNodeOutputs, bytes memory parameters, bytes32[] memory runtimeKeys, - bytes32[] memory runtimeValuess + bytes32[] memory runtimeValues ) external view returns (NodeOutput.Data memory); function isValid(NodeDefinition.Data memory nodeDefinition) external returns (bool); diff --git a/protocol/oracle-manager/contracts/modules/NodeModule.sol b/protocol/oracle-manager/contracts/modules/NodeModule.sol index 5670706d5a..c09e096f19 100644 --- a/protocol/oracle-manager/contracts/modules/NodeModule.sol +++ b/protocol/oracle-manager/contracts/modules/NodeModule.sol @@ -14,6 +14,8 @@ import "../nodes/ConstantNode.sol"; import "../storage/NodeOutput.sol"; import "../storage/NodeDefinition.sol"; +import "@synthetixio/core-contracts/contracts/errors/ParameterError.sol"; + /** * @title Module for managing nodes * @dev See INodeModule. @@ -151,6 +153,13 @@ contract NodeModule is INodeModule { bytes32[] memory runtimeKeys, bytes32[] memory runtimeValues ) internal view returns (NodeOutput.Data memory price) { + if (runtimeKeys.length != runtimeValues.length) { + revert ParameterError.InvalidParameter( + "runtimeValues", + "must be same length as runtimeKeys" + ); + } + NodeDefinition.Data memory nodeDefinition = NodeDefinition.load(nodeId); if (nodeDefinition.nodeType == NodeDefinition.NodeType.REDUCER) { From e7344944d969ff5adf3b4e3ed40b43e7cc4bda1e Mon Sep 17 00:00:00 2001 From: Noisekit Date: Tue, 8 Aug 2023 10:30:53 +0800 Subject: [PATCH 35/63] Combined Readme for all contracts (#1723) * Remove "Solidity API" header from page template * Enable git diff check for docs * Generate full v3 Contracts page * Global docgen github action * Adjust headings level for contracts * Add TOC * Add "Back to TOC" link * Regenerate docs --- .github/workflows/docgen.yml | 22 + .github/workflows/test.yml | 10 - docs/Contracts.md | 6116 +++++++++++++++++++++++ markets/perps-market/docs/index.md | 743 ++- markets/spot-market/docs/index.md | 226 +- package.json | 3 +- protocol/governance/docs/index.md | 266 +- protocol/oracle-manager/docs/index.md | 104 +- protocol/synthetix/docs/index.md | 414 +- utils/docgen/docgen:contracts.sh | 45 + utils/docgen/natspec/theme/contract.hbs | 2 +- utils/docgen/natspec/theme/helpers.ts | 2 +- utils/docgen/natspec/theme/page.hbs | 6 + utils/docgen/package.json | 3 +- 14 files changed, 7290 insertions(+), 672 deletions(-) create mode 100644 .github/workflows/docgen.yml create mode 100644 docs/Contracts.md create mode 100755 utils/docgen/docgen:contracts.sh create mode 100644 utils/docgen/natspec/theme/page.hbs diff --git a/.github/workflows/docgen.yml b/.github/workflows/docgen.yml new file mode 100644 index 0000000000..4cea9c3074 --- /dev/null +++ b/.github/workflows/docgen.yml @@ -0,0 +1,22 @@ +name: Docgen + +on: + pull_request: {} + push: + branches: + - "main" + +jobs: + docgen: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-node@v3 + with: + node-version: "18.16.0" + cache: "yarn" + - run: yarn --version + - run: yarn install --immutable --immutable-cache + - run: yarn workspaces foreach --topological-dev --verbose run build:ts + - run: yarn docgen + - run: git diff --exit-code diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 70be7c0d4f..01b734ac9a 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -76,16 +76,6 @@ jobs: - run: yarn workspaces foreach --topological-dev --recursive --verbose --from ${{ matrix.workspace }} run build-testable - - name: Regenerate docs and check for changes - run: | - if yarn workspace ${{ matrix.workspace }} run | grep docgen; then - yarn workspace ${{ matrix.workspace }} run docgen - # TODO: for some reason we have some diff in CI and not locally. - # git diff --exit-code - else - echo 'SKIP. No "docgen" script' - fi - - name: Execute size-contracts command run: | if yarn workspace ${{ matrix.workspace }} run | grep size-contracts; then diff --git a/docs/Contracts.md b/docs/Contracts.md new file mode 100644 index 0000000000..72e8096b1d --- /dev/null +++ b/docs/Contracts.md @@ -0,0 +1,6116 @@ +# Smart Contracts + +- [Synthetix Core](#synthetix-core) +- [Spot Market](#spot-market) +- [Perps Market](#perps-market) +- [Governance](#governance) +- [Oracle Manager](#oracle-manager) + +## Synthetix Core + +### Account Module + +#### getAccountPermissions + + ```solidity + function getAccountPermissions(uint128 accountId) external view returns (struct IAccountModule.AccountPermissions[] accountPerms) + ``` + + Returns an array of `AccountPermission` for the provided `accountId`. + +**Parameters** +* `accountId` (*uint128*) - The id of the account whose permissions are being retrieved. + +**Returns** +* `accountPerms` (*struct IAccountModule.AccountPermissions[]*) - An array of AccountPermission objects describing the permissions granted to the account. +#### createAccount + + ```solidity + function createAccount(uint128 requestedAccountId) external + ``` + + Mints an account token with id `requestedAccountId` to `msg.sender`. + +**Parameters** +* `requestedAccountId` (*uint128*) - The id requested for the account being created. Reverts if id already exists. Requirements: - `requestedAccountId` must not already be minted. - `requestedAccountId` must be less than type(uint128).max / 2 Emits a {AccountCreated} event. + +#### createAccount + + ```solidity + function createAccount() external returns (uint128 accountId) + ``` + + Mints an account token with an available id to `msg.sender`. + +Emits a {AccountCreated} event. + +#### notifyAccountTransfer + + ```solidity + function notifyAccountTransfer(address to, uint128 accountId) external + ``` + + Called by AccountTokenModule to notify the system when the account token is transferred. + + Resets user permissions and assigns ownership of the account token to the new holder. + +**Parameters** +* `to` (*address*) - The new holder of the account NFT. +* `accountId` (*uint128*) - The id of the account that was just transferred. Requirements: - `msg.sender` must be the account token. + +#### grantPermission + + ```solidity + function grantPermission(uint128 accountId, bytes32 permission, address user) external + ``` + + Grants `permission` to `user` for account `accountId`. + +**Parameters** +* `accountId` (*uint128*) - The id of the account that granted the permission. +* `permission` (*bytes32*) - The bytes32 identifier of the permission. +* `user` (*address*) - The target address that received the permission. Requirements: - `msg.sender` must own the account token with ID `accountId` or have the "admin" permission. Emits a {PermissionGranted} event. + +#### revokePermission + + ```solidity + function revokePermission(uint128 accountId, bytes32 permission, address user) external + ``` + + Revokes `permission` from `user` for account `accountId`. + +**Parameters** +* `accountId` (*uint128*) - The id of the account that revoked the permission. +* `permission` (*bytes32*) - The bytes32 identifier of the permission. +* `user` (*address*) - The target address that no longer has the permission. Requirements: - `msg.sender` must own the account token with ID `accountId` or have the "admin" permission. Emits a {PermissionRevoked} event. + +#### renouncePermission + + ```solidity + function renouncePermission(uint128 accountId, bytes32 permission) external + ``` + + Revokes `permission` from `msg.sender` for account `accountId`. + +**Parameters** +* `accountId` (*uint128*) - The id of the account whose permission was renounced. +* `permission` (*bytes32*) - The bytes32 identifier of the permission. Emits a {PermissionRevoked} event. + +#### hasPermission + + ```solidity + function hasPermission(uint128 accountId, bytes32 permission, address user) external view returns (bool hasPermission) + ``` + + Returns `true` if `user` has been granted `permission` for account `accountId`. + +**Parameters** +* `accountId` (*uint128*) - The id of the account whose permission is being queried. +* `permission` (*bytes32*) - The bytes32 identifier of the permission. +* `user` (*address*) - The target address whose permission is being queried. + +**Returns** +* `hasPermission` (*bool*) - A boolean with the response of the query. +#### isAuthorized + + ```solidity + function isAuthorized(uint128 accountId, bytes32 permission, address target) external view returns (bool isAuthorized) + ``` + + Returns `true` if `target` is authorized to `permission` for account `accountId`. + +**Parameters** +* `accountId` (*uint128*) - The id of the account whose permission is being queried. +* `permission` (*bytes32*) - The bytes32 identifier of the permission. +* `target` (*address*) - The target address whose permission is being queried. + +**Returns** +* `isAuthorized` (*bool*) - A boolean with the response of the query. +#### getAccountTokenAddress + + ```solidity + function getAccountTokenAddress() external view returns (address accountNftToken) + ``` + + Returns the address for the account token used by the module. + +**Returns** +* `accountNftToken` (*address*) - The address of the account token. +#### getAccountOwner + + ```solidity + function getAccountOwner(uint128 accountId) external view returns (address owner) + ``` + + Returns the address that owns a given account, as recorded by the system. + +**Parameters** +* `accountId` (*uint128*) - The account id whose owner is being retrieved. + +**Returns** +* `owner` (*address*) - The owner of the given account id. +#### getAccountLastInteraction + + ```solidity + function getAccountLastInteraction(uint128 accountId) external view returns (uint256 timestamp) + ``` + + Returns the last unix timestamp that a permissioned action was taken with this account + +**Parameters** +* `accountId` (*uint128*) - The account id to check + +**Returns** +* `timestamp` (*uint256*) - The unix timestamp of the last time a permissioned action occured with the account + +#### AccountCreated + + ```solidity + event AccountCreated(uint128 accountId, address owner) + ``` + + Emitted when an account token with id `accountId` is minted to `sender`. + +**Parameters** +* `accountId` (*uint128*) - The id of the account. +* `owner` (*address*) - The address that owns the created account. + +#### PermissionGranted + + ```solidity + event PermissionGranted(uint128 accountId, bytes32 permission, address user, address sender) + ``` + + Emitted when `user` is granted `permission` by `sender` for account `accountId`. + +**Parameters** +* `accountId` (*uint128*) - The id of the account that granted the permission. +* `permission` (*bytes32*) - The bytes32 identifier of the permission. +* `user` (*address*) - The target address to whom the permission was granted. +* `sender` (*address*) - The Address that granted the permission. + +#### PermissionRevoked + + ```solidity + event PermissionRevoked(uint128 accountId, bytes32 permission, address user, address sender) + ``` + + Emitted when `user` has `permission` renounced or revoked by `sender` for account `accountId`. + +**Parameters** +* `accountId` (*uint128*) - The id of the account that has had the permission revoked. +* `permission` (*bytes32*) - The bytes32 identifier of the permission. +* `user` (*address*) - The target address for which the permission was revoked. +* `sender` (*address*) - The address that revoked the permission. + +### Account Token Module + +#### isInitialized + + ```solidity + function isInitialized() external returns (bool) + ``` + + Returns whether the token has been initialized. + +**Returns** +* `[0]` (*bool*) - A boolean with the result of the query. +#### initialize + + ```solidity + function initialize(string tokenName, string tokenSymbol, string uri) external + ``` + + Initializes the token with name, symbol, and uri. + +#### mint + + ```solidity + function mint(address to, uint256 tokenId) external + ``` + + Allows the owner to mint tokens. + +**Parameters** +* `to` (*address*) - The address to receive the newly minted tokens. +* `tokenId` (*uint256*) - The ID of the newly minted token + +#### safeMint + + ```solidity + function safeMint(address to, uint256 tokenId, bytes data) external + ``` + + Allows the owner to mint tokens. Verifies that the receiver can receive the token + +**Parameters** +* `to` (*address*) - The address to receive the newly minted token. +* `tokenId` (*uint256*) - The ID of the newly minted token +* `data` (*bytes*) - any data which should be sent to the receiver + +#### burn + + ```solidity + function burn(uint256 tokenId) external + ``` + + Allows the owner to burn tokens. + +**Parameters** +* `tokenId` (*uint256*) - The token to burn + +#### setAllowance + + ```solidity + function setAllowance(uint256 tokenId, address spender) external + ``` + + Allows an address that holds tokens to provide allowance to another. + +**Parameters** +* `tokenId` (*uint256*) - The token which should be allowed to spender +* `spender` (*address*) - The address that is given allowance. + +#### setBaseTokenURI + + ```solidity + function setBaseTokenURI(string uri) external + ``` + + Allows the owner to update the base token URI. + +**Parameters** +* `uri` (*string*) - The new base token uri + +#### totalSupply + + ```solidity + function totalSupply() external view returns (uint256) + ``` + + Returns the total amount of tokens stored by the contract. + +#### tokenOfOwnerByIndex + + ```solidity + function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256) + ``` + + Returns a token ID owned by `owner` at a given `index` of its token list. +Use along with {balanceOf} to enumerate all of ``owner``'s tokens. + +Requirements: +- `owner` must be a valid address +- `index` must be less than the balance of the tokens for the owner + +#### tokenByIndex + + ```solidity + function tokenByIndex(uint256 index) external view returns (uint256) + ``` + + Returns a token ID at a given `index` of all the tokens stored by the contract. +Use along with {totalSupply} to enumerate all tokens. + +Requirements: +- `index` must be less than the total supply of the tokens + +#### balanceOf + + ```solidity + function balanceOf(address holder) external view returns (uint256 balance) + ``` + + Returns the number of tokens in ``owner``'s account. + +Requirements: + +- `holder` must be a valid address + +#### ownerOf + + ```solidity + function ownerOf(uint256 tokenId) external view returns (address owner) + ``` + + Returns the owner of the `tokenId` token. + +Requirements: + +- `tokenId` must exist. + +#### safeTransferFrom + + ```solidity + function safeTransferFrom(address from, address to, uint256 tokenId, bytes data) external + ``` + + Safely transfers `tokenId` token from `from` to `to`. + +Requirements: + +- `from` cannot be the zero address. +- `to` cannot be the zero address. +- `tokenId` token must exist and be owned by `from`. +- If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. +- If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. + +Emits a {Transfer} event. + +#### safeTransferFrom + + ```solidity + function safeTransferFrom(address from, address to, uint256 tokenId) external + ``` + + Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients +are aware of the ERC721 protocol to prevent tokens from being forever locked. + +Requirements: + +- `from` cannot be the zero address. +- `to` cannot be the zero address. +- `tokenId` token must exist and be owned by `from`. +- If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}. +- If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. + +Emits a {Transfer} event. + +#### transferFrom + + ```solidity + function transferFrom(address from, address to, uint256 tokenId) external + ``` + + Transfers `tokenId` token from `from` to `to`. + +WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible. + +Requirements: + +- `from` cannot be the zero address. +- `to` cannot be the zero address. +- `tokenId` token must be owned by `from`. +- If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. + +Emits a {Transfer} event. + +#### approve + + ```solidity + function approve(address to, uint256 tokenId) external + ``` + + Gives permission to `to` to transfer `tokenId` token to another account. +The approval is cleared when the token is transferred. + +Only a single account can be approved at a time, so approving the zero address clears previous approvals. + +Requirements: + +- The caller must own the token or be an approved operator. +- `tokenId` must exist. + +Emits an {Approval} event. + +#### setApprovalForAll + + ```solidity + function setApprovalForAll(address operator, bool approved) external + ``` + + Approve or remove `operator` as an operator for the caller. +Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. + +Requirements: + +- The `operator` cannot be the caller. + +Emits an {ApprovalForAll} event. + +#### getApproved + + ```solidity + function getApproved(uint256 tokenId) external view returns (address operator) + ``` + + Returns the account approved for `tokenId` token. + +Requirements: + +- `tokenId` must exist. + +#### isApprovedForAll + + ```solidity + function isApprovedForAll(address owner, address operator) external view returns (bool) + ``` + + Returns if the `operator` is allowed to manage all of the assets of `owner`. + +See {setApprovalForAll} + +#### Transfer + + ```solidity + event Transfer(address from, address to, uint256 tokenId) + ``` + + Emitted when `tokenId` token is transferred from `from` to `to`. + +#### Approval + + ```solidity + event Approval(address owner, address approved, uint256 tokenId) + ``` + + Emitted when `owner` enables `approved` to manage the `tokenId` token. + +#### ApprovalForAll + + ```solidity + event ApprovalForAll(address owner, address operator, bool approved) + ``` + + Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets. + +### Associate Debt Module + +#### associateDebt + + ```solidity + function associateDebt(uint128 marketId, uint128 poolId, address collateralType, uint128 accountId, uint256 amount) external returns (int256 debtAmount) + ``` + + Allows a market to associate debt with a specific position. +The specified debt will be removed from all vault participants pro-rata. After removing the debt, the amount will +be allocated directly to the specified account. +**NOTE**: if the specified account is an existing staker on the vault, their position will be included in the pro-rata +reduction. Ex: if there are 10 users staking 10 USD of debt on a pool, and associate debt is called with 10 USD on one of those users, +their debt after the operation is complete will be 19 USD. This might seem unusual, but its actually ideal behavior when +your market has incurred some new debt, and it wants to allocate this amount directly to a specific user. In this case, the user's +debt balance would increase pro rata, but then get decreased pro-rata, and then increased to the full amount on their account. All +other accounts would be left with no change to their debt, however. + +**Parameters** +* `marketId` (*uint128*) - The id of the market to which debt was associated. +* `poolId` (*uint128*) - The id of the pool associated to the target market. +* `collateralType` (*address*) - The address of the collateral type that acts as collateral in the corresponding pool. +* `accountId` (*uint128*) - The id of the account whose debt is being associated. +* `amount` (*uint256*) - The amount of debt being associated with the specified account, denominated with 18 decimals of precision. + +**Returns** +* `debtAmount` (*int256*) - The updated debt of the position, denominated with 18 decimals of precision. + +#### DebtAssociated + + ```solidity + event DebtAssociated(uint128 marketId, uint128 poolId, address collateralType, uint128 accountId, uint256 amount, int256 updatedDebt) + ``` + + Emitted when `associateDebt` is called. + +**Parameters** +* `marketId` (*uint128*) - The id of the market to which debt was associated. +* `poolId` (*uint128*) - The id of the pool associated to the target market. +* `collateralType` (*address*) - The address of the collateral type that acts as collateral in the corresponding pool. +* `accountId` (*uint128*) - The id of the account whose debt is being associated. +* `amount` (*uint256*) - The amount of debt being associated with the specified account, denominated with 18 decimals of precision. +* `updatedDebt` (*int256*) - The total updated debt of the account, denominated with 18 decimals of precision + +### Collateral Configuration Module + +#### configureCollateral + + ```solidity + function configureCollateral(struct CollateralConfiguration.Data config) external + ``` + + Creates or updates the configuration for the given `collateralType`. + +**Parameters** +* `config` (*struct CollateralConfiguration.Data*) - The CollateralConfiguration object describing the new configuration. Requirements: - `msg.sender` must be the owner of the system. Emits a {CollateralConfigured} event. + +#### getCollateralConfigurations + + ```solidity + function getCollateralConfigurations(bool hideDisabled) external view returns (struct CollateralConfiguration.Data[] collaterals) + ``` + + Returns a list of detailed information pertaining to all collateral types registered in the system. + + Optionally returns only those that are currently enabled. + +**Parameters** +* `hideDisabled` (*bool*) - Wether to hide disabled collaterals or just return the full list of collaterals in the system. + +**Returns** +* `collaterals` (*struct CollateralConfiguration.Data[]*) - The list of collateral configuration objects set in the system. +#### getCollateralConfiguration + + ```solidity + function getCollateralConfiguration(address collateralType) external view returns (struct CollateralConfiguration.Data collateral) + ``` + + Returns detailed information pertaining the specified collateral type. + +**Parameters** +* `collateralType` (*address*) - The address for the collateral whose configuration is being queried. + +**Returns** +* `collateral` (*struct CollateralConfiguration.Data*) - The configuration object describing the given collateral. +#### getCollateralPrice + + ```solidity + function getCollateralPrice(address collateralType) external view returns (uint256 priceD18) + ``` + + Returns the current value of a specified collateral type. + +**Parameters** +* `collateralType` (*address*) - The address for the collateral whose price is being queried. + +**Returns** +* `priceD18` (*uint256*) - The price of the given collateral, denominated with 18 decimals of precision. + +#### CollateralConfigured + + ```solidity + event CollateralConfigured(address collateralType, struct CollateralConfiguration.Data config) + ``` + + Emitted when a collateral type’s configuration is created or updated. + +**Parameters** +* `collateralType` (*address*) - The address of the collateral type that was just configured. +* `config` (*struct CollateralConfiguration.Data*) - The object with the newly configured details. + +### Collateral Module + +#### deposit + + ```solidity + function deposit(uint128 accountId, address collateralType, uint256 tokenAmount) external + ``` + + Deposits `tokenAmount` of collateral of type `collateralType` into account `accountId`. + + Anyone can deposit into anyone's active account without restriction. + +**Parameters** +* `accountId` (*uint128*) - The id of the account that is making the deposit. +* `collateralType` (*address*) - The address of the token to be deposited. +* `tokenAmount` (*uint256*) - The amount being deposited, denominated in the token's native decimal representation. Emits a {Deposited} event. + +#### withdraw + + ```solidity + function withdraw(uint128 accountId, address collateralType, uint256 tokenAmount) external + ``` + + Withdraws `tokenAmount` of collateral of type `collateralType` from account `accountId`. + +**Parameters** +* `accountId` (*uint128*) - The id of the account that is making the withdrawal. +* `collateralType` (*address*) - The address of the token to be withdrawn. +* `tokenAmount` (*uint256*) - The amount being withdrawn, denominated in the token's native decimal representation. Requirements: - `msg.sender` must be the owner of the account, have the `ADMIN` permission, or have the `WITHDRAW` permission. Emits a {Withdrawn} event. + +#### getAccountCollateral + + ```solidity + function getAccountCollateral(uint128 accountId, address collateralType) external view returns (uint256 totalDeposited, uint256 totalAssigned, uint256 totalLocked) + ``` + + Returns the total values pertaining to account `accountId` for `collateralType`. + +**Parameters** +* `accountId` (*uint128*) - The id of the account whose collateral is being queried. +* `collateralType` (*address*) - The address of the collateral type whose amount is being queried. + +**Returns** +* `totalDeposited` (*uint256*) - The total collateral deposited in the account, denominated with 18 decimals of precision. +* `totalAssigned` (*uint256*) - The amount of collateral in the account that is delegated to pools, denominated with 18 decimals of precision. +* `totalLocked` (*uint256*) - The amount of collateral in the account that cannot currently be undelegated from a pool, denominated with 18 decimals of precision. +#### getAccountAvailableCollateral + + ```solidity + function getAccountAvailableCollateral(uint128 accountId, address collateralType) external view returns (uint256 amountD18) + ``` + + Returns the amount of collateral of type `collateralType` deposited with account `accountId` that can be withdrawn or delegated to pools. + +**Parameters** +* `accountId` (*uint128*) - The id of the account whose collateral is being queried. +* `collateralType` (*address*) - The address of the collateral type whose amount is being queried. + +**Returns** +* `amountD18` (*uint256*) - The amount of collateral that is available for withdrawal or delegation, denominated with 18 decimals of precision. +#### cleanExpiredLocks + + ```solidity + function cleanExpiredLocks(uint128 accountId, address collateralType, uint256 offset, uint256 count) external returns (uint256 cleared) + ``` + + Clean expired locks from locked collateral arrays for an account/collateral type. It includes offset and items to prevent gas exhaustion. If both, offset and items, are 0 it will traverse the whole array (unlimited). + +**Parameters** +* `accountId` (*uint128*) - The id of the account whose locks are being cleared. +* `collateralType` (*address*) - The address of the collateral type to clean locks for. +* `offset` (*uint256*) - The index of the first lock to clear. +* `count` (*uint256*) - The number of slots to check for cleaning locks. Set to 0 to clean all locks at/after offset + +**Returns** +* `cleared` (*uint256*) - the number of locks that were actually expired (and therefore cleared) +#### getLocks + + ```solidity + function getLocks(uint128 accountId, address collateralType, uint256 offset, uint256 count) external view returns (struct CollateralLock.Data[] locks) + ``` + + Get a list of locks existing in account. Lists all locks in storage, even if they are expired + +**Parameters** +* `accountId` (*uint128*) - The id of the account whose locks we want to read +* `collateralType` (*address*) - The address of the collateral type for locks we want to read +* `offset` (*uint256*) - The index of the first lock to read +* `count` (*uint256*) - The number of slots to check for cleaning locks. Set to 0 to read all locks after offset + +#### createLock + + ```solidity + function createLock(uint128 accountId, address collateralType, uint256 amount, uint64 expireTimestamp) external + ``` + + Create a new lock on the given account. you must have `admin` permission on the specified account to create a lock. + + Collateral can be withdrawn from the system if it is not assigned or delegated to a pool. Collateral locks are an additional restriction that applies on top of that. I.e. if collateral is not assigned to a pool, but has a lock, it cannot be withdrawn. +Collateral locks are initially intended for the Synthetix v2 to v3 migration, but may be used in the future by the Spartan Council, for example, to create and hand off accounts whose withdrawals from the system are locked for a given amount of time. + +**Parameters** +* `accountId` (*uint128*) - The id of the account for which a lock is to be created. +* `collateralType` (*address*) - The address of the collateral type for which the lock will be created. +* `amount` (*uint256*) - The amount of collateral tokens to wrap in the lock being created, denominated with 18 decimals of precision. +* `expireTimestamp` (*uint64*) - The date in which the lock will become clearable. + +#### Deposited + + ```solidity + event Deposited(uint128 accountId, address collateralType, uint256 tokenAmount, address sender) + ``` + + Emitted when `tokenAmount` of collateral of type `collateralType` is deposited to account `accountId` by `sender`. + +**Parameters** +* `accountId` (*uint128*) - The id of the account that deposited collateral. +* `collateralType` (*address*) - The address of the collateral that was deposited. +* `tokenAmount` (*uint256*) - The amount of collateral that was deposited, denominated in the token's native decimal representation. +* `sender` (*address*) - The address of the account that triggered the deposit. + +#### CollateralLockCreated + + ```solidity + event CollateralLockCreated(uint128 accountId, address collateralType, uint256 tokenAmount, uint64 expireTimestamp) + ``` + + Emitted when a lock is created on someone's account + +**Parameters** +* `accountId` (*uint128*) - The id of the account that received a lock +* `collateralType` (*address*) - The address of the collateral type that was locked +* `tokenAmount` (*uint256*) - The amount of collateral that was locked, demoninated in system units (1e18) +* `expireTimestamp` (*uint64*) - unix timestamp at which the lock is due to expire + +#### CollateralLockExpired + + ```solidity + event CollateralLockExpired(uint128 accountId, address collateralType, uint256 tokenAmount, uint64 expireTimestamp) + ``` + + Emitted when a lock is cleared from an account due to expiration + +**Parameters** +* `accountId` (*uint128*) - The id of the account that has the expired lock +* `collateralType` (*address*) - The address of the collateral type that was unlocked +* `tokenAmount` (*uint256*) - The amount of collateral that was unlocked, demoninated in system units (1e18) +* `expireTimestamp` (*uint64*) - unix timestamp at which the unlock is due to expire + +#### Withdrawn + + ```solidity + event Withdrawn(uint128 accountId, address collateralType, uint256 tokenAmount, address sender) + ``` + + Emitted when `tokenAmount` of collateral of type `collateralType` is withdrawn from account `accountId` by `sender`. + +**Parameters** +* `accountId` (*uint128*) - The id of the account that withdrew collateral. +* `collateralType` (*address*) - The address of the collateral that was withdrawn. +* `tokenAmount` (*uint256*) - The amount of collateral that was withdrawn, denominated in the token's native decimal representation. +* `sender` (*address*) - The address of the account that triggered the withdrawal. + +### Cross ChainUSD Module + +#### transferCrossChain + + ```solidity + function transferCrossChain(uint64 destChainId, uint256 amount) external payable returns (uint256 gasTokenUsed) + ``` + + Allows users to transfer tokens cross-chain using CCIP. + +**Parameters** +* `destChainId` (*uint64*) - The id of the chain where tokens are to be transferred to. +* `amount` (*uint256*) - The amount of tokens to be transferred, denominated with 18 decimals of precision. + +**Returns** +* `gasTokenUsed` (*uint256*) - The amount of fees paid in the cross-chain transfer, denominated with 18 decimals of precision. + +#### TransferCrossChainInitiated + + ```solidity + event TransferCrossChainInitiated(uint64 destChainId, uint256 amount, address sender) + ``` + +### IssueUSD Module + +#### mintUsd + + ```solidity + function mintUsd(uint128 accountId, uint128 poolId, address collateralType, uint256 amount) external + ``` + + Mints {amount} of snxUSD with the specified liquidity position. + +**Parameters** +* `accountId` (*uint128*) - The id of the account that is minting snxUSD. +* `poolId` (*uint128*) - The id of the pool whose collateral will be used to back up the mint. +* `collateralType` (*address*) - The address of the collateral that will be used to back up the mint. +* `amount` (*uint256*) - The amount of snxUSD to be minted, denominated with 18 decimals of precision. Requirements: - `msg.sender` must be the owner of the account, have the `ADMIN` permission, or have the `MINT` permission. - After minting, the collateralization ratio of the liquidity position must not be below the target collateralization ratio for the corresponding collateral type. Emits a {UsdMinted} event. + +#### burnUsd + + ```solidity + function burnUsd(uint128 accountId, uint128 poolId, address collateralType, uint256 amount) external + ``` + + Burns {amount} of snxUSD with the specified liquidity position. + +**Parameters** +* `accountId` (*uint128*) - The id of the account that is burning snxUSD. +* `poolId` (*uint128*) - The id of the pool whose collateral was used to back up the snxUSD. +* `collateralType` (*address*) - The address of the collateral that was used to back up the snxUSD. +* `amount` (*uint256*) - The amount of snxUSD to be burnt, denominated with 18 decimals of precision. Emits a {UsdMinted} event. + +#### UsdMinted + + ```solidity + event UsdMinted(uint128 accountId, uint128 poolId, address collateralType, uint256 amount, address sender) + ``` + + Emitted when {sender} mints {amount} of snxUSD with the specified liquidity position. + +**Parameters** +* `accountId` (*uint128*) - The id of the account for which snxUSD was emitted. +* `poolId` (*uint128*) - The id of the pool whose collateral was used to emit the snxUSD. +* `collateralType` (*address*) - The address of the collateral that is backing up the emitted snxUSD. +* `amount` (*uint256*) - The amount of snxUSD emitted, denominated with 18 decimals of precision. +* `sender` (*address*) - The address that triggered the operation. + +#### UsdBurned + + ```solidity + event UsdBurned(uint128 accountId, uint128 poolId, address collateralType, uint256 amount, address sender) + ``` + + Emitted when {sender} burns {amount} of snxUSD with the specified liquidity position. + +**Parameters** +* `accountId` (*uint128*) - The id of the account for which snxUSD was burned. +* `poolId` (*uint128*) - The id of the pool whose collateral was used to emit the snxUSD. +* `collateralType` (*address*) - The address of the collateral that was backing up the emitted snxUSD. +* `amount` (*uint256*) - The amount of snxUSD burned, denominated with 18 decimals of precision. +* `sender` (*address*) - The address that triggered the operation. + +#### IssuanceFeePaid + + ```solidity + event IssuanceFeePaid(uint128 accountId, uint128 poolId, address collateralType, uint256 feeAmount) + ``` + +### Liquidation Module + +#### liquidate + + ```solidity + function liquidate(uint128 accountId, uint128 poolId, address collateralType, uint128 liquidateAsAccountId) external returns (struct ILiquidationModule.LiquidationData liquidationData) + ``` + + Liquidates a position by distributing its debt and collateral among other positions in its vault. + +**Parameters** +* `accountId` (*uint128*) - The id of the account whose position is to be liquidated. +* `poolId` (*uint128*) - The id of the pool which holds the position that is to be liquidated. +* `collateralType` (*address*) - The address of the collateral being used in the position that is to be liquidated. +* `liquidateAsAccountId` (*uint128*) - Account id that will receive the rewards from the liquidation. + +**Returns** +* `liquidationData` (*struct ILiquidationModule.LiquidationData*) - Information about the position that was liquidated. +#### liquidateVault + + ```solidity + function liquidateVault(uint128 poolId, address collateralType, uint128 liquidateAsAccountId, uint256 maxUsd) external returns (struct ILiquidationModule.LiquidationData liquidationData) + ``` + + Liquidates an entire vault. + + Can only be done if the vault itself is under collateralized. +LiquidateAsAccountId determines which account to deposit the seized collateral into (this is necessary particularly if the collateral in the vault is vesting). +Will only liquidate a portion of the debt for the vault if `maxUsd` is supplied. + +**Parameters** +* `poolId` (*uint128*) - The id of the pool whose vault is being liquidated. +* `collateralType` (*address*) - The address of the collateral whose vault is being liquidated. +* `liquidateAsAccountId` (*uint128*) - +* `maxUsd` (*uint256*) - The maximum amount of USD that the liquidator is willing to provide for the liquidation, denominated with 18 decimals of precision. + +**Returns** +* `liquidationData` (*struct ILiquidationModule.LiquidationData*) - Information about the vault that was liquidated. +#### isPositionLiquidatable + + ```solidity + function isPositionLiquidatable(uint128 accountId, uint128 poolId, address collateralType) external returns (bool canLiquidate) + ``` + + Determines whether a specified position is liquidatable. + +**Parameters** +* `accountId` (*uint128*) - The id of the account whose position is being queried for liquidation. +* `poolId` (*uint128*) - The id of the pool whose position is being queried for liquidation. +* `collateralType` (*address*) - The address of the collateral backing up the position being queried for liquidation. + +**Returns** +* `canLiquidate` (*bool*) - A boolean with the response to the query. +#### isVaultLiquidatable + + ```solidity + function isVaultLiquidatable(uint128 poolId, address collateralType) external returns (bool canVaultLiquidate) + ``` + + Determines whether a specified vault is liquidatable. + +**Parameters** +* `poolId` (*uint128*) - The id of the pool that owns the vault that is being queried for liquidation. +* `collateralType` (*address*) - The address of the collateral being held at the vault that is being queried for liquidation. + +**Returns** +* `canVaultLiquidate` (*bool*) - A boolean with the response to the query. + +#### Liquidation + + ```solidity + event Liquidation(uint128 accountId, uint128 poolId, address collateralType, struct ILiquidationModule.LiquidationData liquidationData, uint128 liquidateAsAccountId, address sender) + ``` + + Emitted when an account is liquidated. + +**Parameters** +* `accountId` (*uint128*) - The id of the account that was liquidated. +* `poolId` (*uint128*) - The pool id of the position that was liquidated. +* `collateralType` (*address*) - The collateral type used in the position that was liquidated. +* `liquidationData` (*struct ILiquidationModule.LiquidationData*) - The amount of collateral liquidated, debt liquidated, and collateral awarded to the liquidator. +* `liquidateAsAccountId` (*uint128*) - Account id that will receive the rewards from the liquidation. +* `sender` (*address*) - The address of the account that is triggering the liquidation. + +#### VaultLiquidation + + ```solidity + event VaultLiquidation(uint128 poolId, address collateralType, struct ILiquidationModule.LiquidationData liquidationData, uint128 liquidateAsAccountId, address sender) + ``` + + Emitted when a vault is liquidated. + +**Parameters** +* `poolId` (*uint128*) - The id of the pool whose vault was liquidated. +* `collateralType` (*address*) - The collateral address of the vault that was liquidated. +* `liquidationData` (*struct ILiquidationModule.LiquidationData*) - The amount of collateral liquidated, debt liquidated, and collateral awarded to the liquidator. +* `liquidateAsAccountId` (*uint128*) - Account id that will receive the rewards from the liquidation. +* `sender` (*address*) - The address of the account that is triggering the liquidation. + +### Market Collateral Module + +#### depositMarketCollateral + + ```solidity + function depositMarketCollateral(uint128 marketId, address collateralType, uint256 amount) external + ``` + + Allows a market to deposit collateral. + +**Parameters** +* `marketId` (*uint128*) - The id of the market in which the collateral was directly deposited. +* `collateralType` (*address*) - The address of the collateral that was deposited in the market. +* `amount` (*uint256*) - The amount of collateral that was deposited, denominated in the token's native decimal representation. + +#### withdrawMarketCollateral + + ```solidity + function withdrawMarketCollateral(uint128 marketId, address collateralType, uint256 amount) external + ``` + + Allows a market to withdraw collateral that it has previously deposited. + +**Parameters** +* `marketId` (*uint128*) - The id of the market from which the collateral was withdrawn. +* `collateralType` (*address*) - The address of the collateral that was withdrawn from the market. +* `amount` (*uint256*) - The amount of collateral that was withdrawn, denominated in the token's native decimal representation. + +#### configureMaximumMarketCollateral + + ```solidity + function configureMaximumMarketCollateral(uint128 marketId, address collateralType, uint256 amount) external + ``` + + Allow the system owner to configure the maximum amount of a given collateral type that a specified market is allowed to deposit. + +**Parameters** +* `marketId` (*uint128*) - The id of the market for which the maximum is to be configured. +* `collateralType` (*address*) - The address of the collateral for which the maximum is to be applied. +* `amount` (*uint256*) - The amount that is to be set as the new maximum, denominated with 18 decimals of precision. + +#### getMaximumMarketCollateral + + ```solidity + function getMaximumMarketCollateral(uint128 marketId, address collateralType) external returns (uint256 amountD18) + ``` + + Return the total maximum amount of a given collateral type that a specified market is allowed to deposit. + +**Parameters** +* `marketId` (*uint128*) - The id of the market for which the maximum is being queried. +* `collateralType` (*address*) - The address of the collateral for which the maximum is being queried. + +**Returns** +* `amountD18` (*uint256*) - The maximum amount of collateral set for the market, denominated with 18 decimals of precision. +#### getMarketCollateralAmount + + ```solidity + function getMarketCollateralAmount(uint128 marketId, address collateralType) external view returns (uint256 amountD18) + ``` + + Return the total amount of a given collateral type that a specified market has deposited. + +**Parameters** +* `marketId` (*uint128*) - The id of the market for which the directly deposited collateral amount is being queried. +* `collateralType` (*address*) - The address of the collateral for which the amount is being queried. + +**Returns** +* `amountD18` (*uint256*) - The total amount of collateral of this type delegated to the market, denominated with 18 decimals of precision. +#### getMarketCollateralValue + + ```solidity + function getMarketCollateralValue(uint128 marketId) external returns (uint256 valueD18) + ``` + + Return the total value of collateral that a specified market has deposited. + +**Parameters** +* `marketId` (*uint128*) - The id of the market for which the directly deposited collateral amount is being queried. + +**Returns** +* `valueD18` (*uint256*) - The total value of collateral deposited by the market, denominated with 18 decimals of precision. + +#### MarketCollateralDeposited + + ```solidity + event MarketCollateralDeposited(uint128 marketId, address collateralType, uint256 tokenAmount, address sender) + ``` + + Emitted when `amount` of collateral of type `collateralType` is deposited to market `marketId` by `sender`. + +**Parameters** +* `marketId` (*uint128*) - The id of the market in which collateral was deposited. +* `collateralType` (*address*) - The address of the collateral that was directly deposited in the market. +* `tokenAmount` (*uint256*) - The amount of tokens that were deposited, denominated in the token's native decimal representation. +* `sender` (*address*) - The address that triggered the deposit. + +#### MarketCollateralWithdrawn + + ```solidity + event MarketCollateralWithdrawn(uint128 marketId, address collateralType, uint256 tokenAmount, address sender) + ``` + + Emitted when `amount` of collateral of type `collateralType` is withdrawn from market `marketId` by `sender`. + +**Parameters** +* `marketId` (*uint128*) - The id of the market from which collateral was withdrawn. +* `collateralType` (*address*) - The address of the collateral that was withdrawn from the market. +* `tokenAmount` (*uint256*) - The amount of tokens that were withdrawn, denominated in the token's native decimal representation. +* `sender` (*address*) - The address that triggered the withdrawal. + +#### MaximumMarketCollateralConfigured + + ```solidity + event MaximumMarketCollateralConfigured(uint128 marketId, address collateralType, uint256 systemAmount, address owner) + ``` + + Emitted when the system owner specifies the maximum depositable collateral of a given type in a given market. + +**Parameters** +* `marketId` (*uint128*) - The id of the market for which the maximum was configured. +* `collateralType` (*address*) - The address of the collateral for which the maximum was configured. +* `systemAmount` (*uint256*) - The amount to which the maximum was set, denominated with 18 decimals of precision. +* `owner` (*address*) - The owner of the system, which triggered the configuration change. + +### Market Manager Module + +#### registerMarket + + ```solidity + function registerMarket(address market) external returns (uint128 newMarketId) + ``` + + Connects an external market to the system. + + Creates a Market object to track the external market, and returns the newly created market id. + +**Parameters** +* `market` (*address*) - The address of the external market that is to be registered in the system. + +**Returns** +* `newMarketId` (*uint128*) - The id with which the market will be registered in the system. +#### depositMarketUsd + + ```solidity + function depositMarketUsd(uint128 marketId, address target, uint256 amount) external returns (uint256 feeAmount) + ``` + + Allows an external market connected to the system to deposit USD in the system. + + The system burns the incoming USD, increases the market's credit capacity, and reduces its issuance. +See `IMarket`. + +**Parameters** +* `marketId` (*uint128*) - The id of the market in which snxUSD will be deposited. +* `target` (*address*) - The address of the account on who's behalf the deposit will be made. +* `amount` (*uint256*) - The amount of snxUSD to be deposited, denominated with 18 decimals of precision. + +**Returns** +* `feeAmount` (*uint256*) - the amount of fees paid (billed as additional debt towards liquidity providers) +#### withdrawMarketUsd + + ```solidity + function withdrawMarketUsd(uint128 marketId, address target, uint256 amount) external returns (uint256 feeAmount) + ``` + + Allows an external market connected to the system to withdraw snxUSD from the system. + + The system mints the requested snxUSD (provided that the market has sufficient credit), reduces the market's credit capacity, and increases its net issuance. +See `IMarket`. + +**Parameters** +* `marketId` (*uint128*) - The id of the market from which snxUSD will be withdrawn. +* `target` (*address*) - The address of the account that will receive the withdrawn snxUSD. +* `amount` (*uint256*) - The amount of snxUSD to be withdraw, denominated with 18 decimals of precision. + +**Returns** +* `feeAmount` (*uint256*) - the amount of fees paid (billed as additional debt towards liquidity providers) +#### getMarketFees + + ```solidity + function getMarketFees(uint128 marketId, uint256 amount) external view returns (uint256 depositFeeAmount, uint256 withdrawFeeAmount) + ``` + + Get the amount of fees paid in USD for a call to `depositMarketUsd` and `withdrawMarketUsd` for the given market and amount + +**Parameters** +* `marketId` (*uint128*) - The market to check fees for +* `amount` (*uint256*) - The amount deposited or withdrawn in USD + +**Returns** +* `depositFeeAmount` (*uint256*) - the amount of USD paid for a call to `depositMarketUsd` +* `withdrawFeeAmount` (*uint256*) - the amount of USD paid for a call to `withdrawMarketUsd` +#### getWithdrawableMarketUsd + + ```solidity + function getWithdrawableMarketUsd(uint128 marketId) external view returns (uint256 withdrawableD18) + ``` + + Returns the total withdrawable snxUSD amount for the specified market. + +**Parameters** +* `marketId` (*uint128*) - The id of the market whose withdrawable USD amount is being queried. + +**Returns** +* `withdrawableD18` (*uint256*) - The total amount of snxUSD that the market could withdraw at the time of the query, denominated with 18 decimals of precision. +#### getMarketNetIssuance + + ```solidity + function getMarketNetIssuance(uint128 marketId) external view returns (int128 issuanceD18) + ``` + + Returns the net issuance of the specified market (snxUSD withdrawn - snxUSD deposited). + +**Parameters** +* `marketId` (*uint128*) - The id of the market whose net issuance is being queried. + +**Returns** +* `issuanceD18` (*int128*) - The net issuance of the market, denominated with 18 decimals of precision. +#### getMarketReportedDebt + + ```solidity + function getMarketReportedDebt(uint128 marketId) external view returns (uint256 reportedDebtD18) + ``` + + Returns the reported debt of the specified market. + +**Parameters** +* `marketId` (*uint128*) - The id of the market whose reported debt is being queried. + +**Returns** +* `reportedDebtD18` (*uint256*) - The market's reported debt, denominated with 18 decimals of precision. +#### getMarketTotalDebt + + ```solidity + function getMarketTotalDebt(uint128 marketId) external view returns (int256 totalDebtD18) + ``` + + Returns the total debt of the specified market. + +**Parameters** +* `marketId` (*uint128*) - The id of the market whose debt is being queried. + +**Returns** +* `totalDebtD18` (*int256*) - The total debt of the market, denominated with 18 decimals of precision. +#### getMarketCollateral + + ```solidity + function getMarketCollateral(uint128 marketId) external view returns (uint256 valueD18) + ``` + + Returns the total snxUSD value of the collateral for the specified market. + +**Parameters** +* `marketId` (*uint128*) - The id of the market whose collateral is being queried. + +**Returns** +* `valueD18` (*uint256*) - The market's total snxUSD value of collateral, denominated with 18 decimals of precision. +#### getMarketDebtPerShare + + ```solidity + function getMarketDebtPerShare(uint128 marketId) external returns (int256 debtPerShareD18) + ``` + + Returns the value per share of the debt of the specified market. + + This is not a view function, and actually updates the entire debt distribution chain. + +**Parameters** +* `marketId` (*uint128*) - The id of the market whose debt per share is being queried. + +**Returns** +* `debtPerShareD18` (*int256*) - The market's debt per share value, denominated with 18 decimals of precision. +#### isMarketCapacityLocked + + ```solidity + function isMarketCapacityLocked(uint128 marketId) external view returns (bool isLocked) + ``` + + Returns whether the capacity of the specified market is locked. + +**Parameters** +* `marketId` (*uint128*) - The id of the market whose capacity is being queried. + +**Returns** +* `isLocked` (*bool*) - A boolean that is true if the market's capacity is locked at the time of the query. +#### getUsdToken + + ```solidity + function getUsdToken() external view returns (contract IERC20) + ``` + + Returns the USD token associated with this synthetix core system + +#### getOracleManager + + ```solidity + function getOracleManager() external view returns (contract IOracleManager) + ``` + + Retrieve the systems' configured oracle manager address + +#### distributeDebtToPools + + ```solidity + function distributeDebtToPools(uint128 marketId, uint256 maxIter) external returns (bool finishedDistributing) + ``` + + Update a market's current debt registration with the system. +This function is provided as an escape hatch for pool griefing, preventing +overwhelming the system with a series of very small pools and creating high gas +costs to update an account. + +**Parameters** +* `marketId` (*uint128*) - the id of the market that needs pools bumped +* `maxIter` (*uint256*) - + +**Returns** +* `finishedDistributing` (*bool*) - whether or not all bumpable pools have been bumped and target price has been reached +#### setMarketMinDelegateTime + + ```solidity + function setMarketMinDelegateTime(uint128 marketId, uint32 minDelegateTime) external + ``` + + allows for a market to set its minimum delegation time. This is useful for preventing stakers from frontrunning rewards or losses +by limiting the frequency of `delegateCollateral` (or `setPoolConfiguration`) calls. By default, there is no minimum delegation time. + +**Parameters** +* `marketId` (*uint128*) - the id of the market that wants to set delegation time. +* `minDelegateTime` (*uint32*) - the minimum number of seconds between delegation calls. Note: this value must be less than the globally defined maximum minDelegateTime + +#### getMarketMinDelegateTime + + ```solidity + function getMarketMinDelegateTime(uint128 marketId) external view returns (uint32) + ``` + + Retrieve the minimum delegation time of a market + +**Parameters** +* `marketId` (*uint128*) - the id of the market + +#### setMinLiquidityRatio + + ```solidity + function setMinLiquidityRatio(uint128 marketId, uint256 minLiquidityRatio) external + ``` + + Allows the system owner (not the pool owner) to set a market-specific minimum liquidity ratio. + +**Parameters** +* `marketId` (*uint128*) - the id of the market +* `minLiquidityRatio` (*uint256*) - The new market-specific minimum liquidity ratio, denominated with 18 decimals of precision. (100% is represented by 1 followed by 18 zeros.) + +#### getMinLiquidityRatio + + ```solidity + function getMinLiquidityRatio(uint128 marketId) external view returns (uint256 minRatioD18) + ``` + + Retrieves the market-specific minimum liquidity ratio. + +**Parameters** +* `marketId` (*uint128*) - the id of the market + +**Returns** +* `minRatioD18` (*uint256*) - The current market-specific minimum liquidity ratio, denominated with 18 decimals of precision. (100% is represented by 1 followed by 18 zeros.) +#### getMarketPools + + ```solidity + function getMarketPools(uint128 marketId) external returns (uint128[] inRangePoolIds, uint128[] outRangePoolIds) + ``` + +#### getMarketPoolDebtDistribution + + ```solidity + function getMarketPoolDebtDistribution(uint128 marketId, uint128 poolId) external returns (uint256 sharesD18, uint128 totalSharesD18, int128 valuePerShareD27) + ``` + +#### MarketRegistered + + ```solidity + event MarketRegistered(address market, uint128 marketId, address sender) + ``` + + Emitted when a new market is registered in the system. + +**Parameters** +* `market` (*address*) - The address of the external market that was registered in the system. +* `marketId` (*uint128*) - The id with which the market was registered in the system. +* `sender` (*address*) - The account that trigger the registration of the market. + +#### MarketUsdDeposited + + ```solidity + event MarketUsdDeposited(uint128 marketId, address target, uint256 amount, address market) + ``` + + Emitted when a market deposits snxUSD in the system. + +**Parameters** +* `marketId` (*uint128*) - The id of the market that deposited snxUSD in the system. +* `target` (*address*) - The address of the account that provided the snxUSD in the deposit. +* `amount` (*uint256*) - The amount of snxUSD deposited in the system, denominated with 18 decimals of precision. +* `market` (*address*) - The address of the external market that is depositing. + +#### MarketUsdWithdrawn + + ```solidity + event MarketUsdWithdrawn(uint128 marketId, address target, uint256 amount, address market) + ``` + + Emitted when a market withdraws snxUSD from the system. + +**Parameters** +* `marketId` (*uint128*) - The id of the market that withdrew snxUSD from the system. +* `target` (*address*) - The address of the account that received the snxUSD in the withdrawal. +* `amount` (*uint256*) - The amount of snxUSD withdrawn from the system, denominated with 18 decimals of precision. +* `market` (*address*) - The address of the external market that is withdrawing. + +#### MarketSystemFeePaid + + ```solidity + event MarketSystemFeePaid(uint128 marketId, uint256 feeAmount) + ``` + +#### SetMinDelegateTime + + ```solidity + event SetMinDelegateTime(uint128 marketId, uint32 minDelegateTime) + ``` + + Emitted when a market sets an updated minimum delegation time + +**Parameters** +* `marketId` (*uint128*) - The id of the market that the setting is applied to +* `minDelegateTime` (*uint32*) - The minimum amount of time between delegation changes + +#### SetMarketMinLiquidityRatio + + ```solidity + event SetMarketMinLiquidityRatio(uint128 marketId, uint256 minLiquidityRatio) + ``` + + Emitted when a market-specific minimum liquidity ratio is set + +**Parameters** +* `marketId` (*uint128*) - The id of the market that the setting is applied to +* `minLiquidityRatio` (*uint256*) - The new market-specific minimum liquidity ratio + +### Multicall Module + +#### multicall + + ```solidity + function multicall(bytes[] data) external payable returns (bytes[] results) + ``` + + Executes multiple transaction payloads in a single transaction. + + Each transaction is executed using `delegatecall`, and targets the system address. + +**Parameters** +* `data` (*bytes[]*) - Array of calldata objects, one for each function that is to be called in the system. + +**Returns** +* `results` (*bytes[]*) - Array of each `delegatecall`'s response corresponding to the incoming calldata array. + +### Pool Configuration Module + +#### setPreferredPool + + ```solidity + function setPreferredPool(uint128 poolId) external + ``` + + Sets the unique system preferred pool. + + Note: The preferred pool does not receive any special treatment. It is only signaled as preferred here. + +**Parameters** +* `poolId` (*uint128*) - The id of the pool that is to be set as preferred. + +#### addApprovedPool + + ```solidity + function addApprovedPool(uint128 poolId) external + ``` + + Marks a pool as approved by the system owner. + + Approved pools do not receive any special treatment. They are only signaled as approved here. + +**Parameters** +* `poolId` (*uint128*) - The id of the pool that is to be approved. + +#### removeApprovedPool + + ```solidity + function removeApprovedPool(uint128 poolId) external + ``` + + Un-marks a pool as preferred by the system owner. + +**Parameters** +* `poolId` (*uint128*) - The id of the pool that is to be no longer approved. + +#### getPreferredPool + + ```solidity + function getPreferredPool() external view returns (uint128 poolId) + ``` + + Retrieves the unique system preferred pool. + +**Returns** +* `poolId` (*uint128*) - The id of the pool that is currently set as preferred in the system. +#### getApprovedPools + + ```solidity + function getApprovedPools() external view returns (uint256[] poolIds) + ``` + + Retrieves the pool that are approved by the system owner. + +**Returns** +* `poolIds` (*uint256[]*) - An array with all of the pool ids that are approved in the system. + +#### PreferredPoolSet + + ```solidity + event PreferredPoolSet(uint256 poolId) + ``` + + Emitted when the system owner sets the preferred pool. + +**Parameters** +* `poolId` (*uint256*) - The id of the pool that was set as preferred. + +#### PoolApprovedAdded + + ```solidity + event PoolApprovedAdded(uint256 poolId) + ``` + + Emitted when the system owner adds an approved pool. + +**Parameters** +* `poolId` (*uint256*) - The id of the pool that was approved. + +#### PoolApprovedRemoved + + ```solidity + event PoolApprovedRemoved(uint256 poolId) + ``` + + Emitted when the system owner removes an approved pool. + +**Parameters** +* `poolId` (*uint256*) - The id of the pool that is no longer approved. + +### Pool Module + +#### createPool + + ```solidity + function createPool(uint128 requestedPoolId, address owner) external + ``` + + Creates a pool with the requested pool id. + +**Parameters** +* `requestedPoolId` (*uint128*) - The requested id for the new pool. Reverts if the id is not available. +* `owner` (*address*) - The address that will own the newly created pool. + +#### setPoolConfiguration + + ```solidity + function setPoolConfiguration(uint128 poolId, struct MarketConfiguration.Data[] marketDistribution) external + ``` + + Allows the pool owner to configure the pool. + + The pool's configuration is composed of an array of MarketConfiguration objects, which describe which markets the pool provides liquidity to, in what proportion, and to what extent. +Incoming market ids need to be provided in ascending order. + +**Parameters** +* `poolId` (*uint128*) - The id of the pool whose configuration is being set. +* `marketDistribution` (*struct MarketConfiguration.Data[]*) - The array of market configuration objects that define the list of markets that are connected to the system. + +#### getPoolConfiguration + + ```solidity + function getPoolConfiguration(uint128 poolId) external view returns (struct MarketConfiguration.Data[] markets) + ``` + + Retrieves the MarketConfiguration of the specified pool. + +**Parameters** +* `poolId` (*uint128*) - The id of the pool whose configuration is being queried. + +**Returns** +* `markets` (*struct MarketConfiguration.Data[]*) - The array of MarketConfiguration objects that describe the pool's configuration. +#### setPoolName + + ```solidity + function setPoolName(uint128 poolId, string name) external + ``` + + Allows the owner of the pool to set the pool's name. + +**Parameters** +* `poolId` (*uint128*) - The id of the pool whose name is being set. +* `name` (*string*) - The new name to give to the pool. + +#### getPoolName + + ```solidity + function getPoolName(uint128 poolId) external view returns (string poolName) + ``` + + Returns the pool's name. + +**Parameters** +* `poolId` (*uint128*) - The id of the pool whose name is being queried. + +**Returns** +* `poolName` (*string*) - The current name of the pool. +#### nominatePoolOwner + + ```solidity + function nominatePoolOwner(address nominatedOwner, uint128 poolId) external + ``` + + Allows the current pool owner to nominate a new owner. + +**Parameters** +* `nominatedOwner` (*address*) - The address to nominate os the new pool owner. +* `poolId` (*uint128*) - The id whose ownership is being transferred. + +#### acceptPoolOwnership + + ```solidity + function acceptPoolOwnership(uint128 poolId) external + ``` + + After a new pool owner has been nominated, allows it to accept the nomination and thus ownership of the pool. + +**Parameters** +* `poolId` (*uint128*) - The id of the pool for which the caller is to accept ownership. + +#### revokePoolNomination + + ```solidity + function revokePoolNomination(uint128 poolId) external + ``` + + After a new pool owner has been nominated, allows it to reject the nomination. + +**Parameters** +* `poolId` (*uint128*) - The id of the pool for which the new owner nomination is to be revoked. + +#### renouncePoolNomination + + ```solidity + function renouncePoolNomination(uint128 poolId) external + ``` + + Allows the current nominated owner to renounce the nomination. + +**Parameters** +* `poolId` (*uint128*) - The id of the pool for which the caller is renouncing ownership nomination. + +#### getPoolOwner + + ```solidity + function getPoolOwner(uint128 poolId) external view returns (address owner) + ``` + + Returns the current pool owner. + +**Parameters** +* `poolId` (*uint128*) - The id of the pool whose ownership is being queried. + +**Returns** +* `owner` (*address*) - The current owner of the pool. +#### getNominatedPoolOwner + + ```solidity + function getNominatedPoolOwner(uint128 poolId) external view returns (address nominatedOwner) + ``` + + Returns the current nominated pool owner. + +**Parameters** +* `poolId` (*uint128*) - The id of the pool whose nominated owner is being queried. + +**Returns** +* `nominatedOwner` (*address*) - The current nominated owner of the pool. +#### setMinLiquidityRatio + + ```solidity + function setMinLiquidityRatio(uint256 minLiquidityRatio) external + ``` + + Allows the system owner (not the pool owner) to set the system-wide minimum liquidity ratio. + +**Parameters** +* `minLiquidityRatio` (*uint256*) - The new system-wide minimum liquidity ratio, denominated with 18 decimals of precision. (100% is represented by 1 followed by 18 zeros.) + +#### getMinLiquidityRatio + + ```solidity + function getMinLiquidityRatio() external view returns (uint256 minRatioD18) + ``` + + Retrieves the system-wide minimum liquidity ratio. + +**Returns** +* `minRatioD18` (*uint256*) - The current system-wide minimum liquidity ratio, denominated with 18 decimals of precision. (100% is represented by 1 followed by 18 zeros.) +#### rebalancePool + + ```solidity + function rebalancePool(uint128 poolId, address optionalCollateralType) external + ``` + + Distributes cached debt in a pool to its vaults and updates market credit capacities. + +**Parameters** +* `poolId` (*uint128*) - the pool to rebalance +* `optionalCollateralType` (*address*) - in addition to rebalancing the pool, calculate updated collaterals and debts for the specified vault + +#### PoolCreated + + ```solidity + event PoolCreated(uint128 poolId, address owner, address sender) + ``` + + Gets fired when pool will be created. + +**Parameters** +* `poolId` (*uint128*) - The id of the newly created pool. +* `owner` (*address*) - The owner of the newly created pool. +* `sender` (*address*) - The address that triggered the creation of the pool. + +#### PoolOwnerNominated + + ```solidity + event PoolOwnerNominated(uint128 poolId, address nominatedOwner, address owner) + ``` + + Gets fired when pool owner proposes a new owner. + +**Parameters** +* `poolId` (*uint128*) - The id of the pool for which the nomination ocurred. +* `nominatedOwner` (*address*) - The address that was nominated as the new owner of the pool. +* `owner` (*address*) - The address of the current owner of the pool. + +#### PoolOwnershipAccepted + + ```solidity + event PoolOwnershipAccepted(uint128 poolId, address owner) + ``` + + Gets fired when pool nominee accepts nomination. + +**Parameters** +* `poolId` (*uint128*) - The id of the pool for which the owner nomination was accepted. +* `owner` (*address*) - The address of the new owner of the pool, which accepted the nomination. + +#### PoolNominationRevoked + + ```solidity + event PoolNominationRevoked(uint128 poolId, address owner) + ``` + + Gets fired when pool owner revokes nomination. + +**Parameters** +* `poolId` (*uint128*) - The id of the pool in which the nomination was revoked. +* `owner` (*address*) - The current owner of the pool. + +#### PoolNominationRenounced + + ```solidity + event PoolNominationRenounced(uint128 poolId, address owner) + ``` + + Gets fired when pool nominee renounces nomination. + +**Parameters** +* `poolId` (*uint128*) - The id of the pool for which the owner nomination was renounced. +* `owner` (*address*) - The current owner of the pool. + +#### PoolNameUpdated + + ```solidity + event PoolNameUpdated(uint128 poolId, string name, address sender) + ``` + + Gets fired when pool name changes. + +**Parameters** +* `poolId` (*uint128*) - The id of the pool whose name was updated. +* `name` (*string*) - The new name of the pool. +* `sender` (*address*) - The address that triggered the rename of the pool. + +#### PoolConfigurationSet + + ```solidity + event PoolConfigurationSet(uint128 poolId, struct MarketConfiguration.Data[] markets, address sender) + ``` + + Gets fired when pool gets configured. + +**Parameters** +* `poolId` (*uint128*) - The id of the pool whose configuration was set. +* `markets` (*struct MarketConfiguration.Data[]*) - Array of configuration data of the markets that were connected to the pool. +* `sender` (*address*) - The address that triggered the pool configuration. + +#### SetMinLiquidityRatio + + ```solidity + event SetMinLiquidityRatio(uint256 minLiquidityRatio) + ``` + + Emitted when a system-wide minimum liquidity ratio is set + +**Parameters** +* `minLiquidityRatio` (*uint256*) - The new system-wide minimum liquidity ratio + +### Rewards Manager Module + +#### registerRewardsDistributor + + ```solidity + function registerRewardsDistributor(uint128 poolId, address collateralType, address distributor) external + ``` + + Called by pool owner to register rewards for vault participants. + +**Parameters** +* `poolId` (*uint128*) - The id of the pool whose rewards are to be managed by the specified distributor. +* `collateralType` (*address*) - The address of the collateral used in the pool's rewards. +* `distributor` (*address*) - The address of the reward distributor to be registered. + +#### removeRewardsDistributor + + ```solidity + function removeRewardsDistributor(uint128 poolId, address collateralType, address distributor) external + ``` + + Called by pool owner to remove a registered rewards distributor for vault participants. +WARNING: if you remove a rewards distributor, the same address can never be re-registered again. If you +simply want to turn off +rewards, call `distributeRewards` with 0 emission. If you need to completely reset the rewards distributor +again, create a new rewards distributor at a new address and register the new one. +This function is provided since the number of rewards distributors added to an account is finite, +so you can remove an unused rewards distributor if need be. +NOTE: unclaimed rewards can still be claimed after a rewards distributor is removed (though any +rewards-over-time will be halted) + +**Parameters** +* `poolId` (*uint128*) - The id of the pool whose rewards are to be managed by the specified distributor. +* `collateralType` (*address*) - The address of the collateral used in the pool's rewards. +* `distributor` (*address*) - The address of the reward distributor to be registered. + +#### distributeRewards + + ```solidity + function distributeRewards(uint128 poolId, address collateralType, uint256 amount, uint64 start, uint32 duration) external + ``` + + Called by a registered distributor to set up rewards for vault participants. + + Will revert if the caller is not a registered distributor. + +**Parameters** +* `poolId` (*uint128*) - The id of the pool to distribute rewards to. +* `collateralType` (*address*) - The address of the collateral used in the pool's rewards. +* `amount` (*uint256*) - The amount of rewards to be distributed. +* `start` (*uint64*) - The date at which the rewards will begin to be claimable. +* `duration` (*uint32*) - The period after which all distributed rewards will be claimable. + +#### claimRewards + + ```solidity + function claimRewards(uint128 accountId, uint128 poolId, address collateralType, address distributor) external returns (uint256 amountClaimedD18) + ``` + + Allows a user with appropriate permissions to claim rewards associated with a position. + +**Parameters** +* `accountId` (*uint128*) - The id of the account that is to claim the rewards. +* `poolId` (*uint128*) - The id of the pool to claim rewards on. +* `collateralType` (*address*) - The address of the collateral used in the pool's rewards. +* `distributor` (*address*) - The address of the rewards distributor associated with the rewards being claimed. + +**Returns** +* `amountClaimedD18` (*uint256*) - The amount of rewards that were available for the account and thus claimed. +#### updateRewards + + ```solidity + function updateRewards(uint128 poolId, address collateralType, uint128 accountId) external returns (uint256[] claimableD18, address[] distributors) + ``` + + For a given position, return the rewards that can currently be claimed. + +**Parameters** +* `poolId` (*uint128*) - The id of the pool being queried. +* `collateralType` (*address*) - The address of the collateral used in the pool's rewards. +* `accountId` (*uint128*) - The id of the account whose available rewards are being queried. + +**Returns** +* `claimableD18` (*uint256[]*) - An array of ids of the reward entries that are claimable by the position. +* `distributors` (*address[]*) - An array with the addresses of the reward distributors associated with the claimable rewards. +#### getRewardRate + + ```solidity + function getRewardRate(uint128 poolId, address collateralType, address distributor) external view returns (uint256 rateD18) + ``` + + Returns the number of individual units of amount emitted per second per share for the given poolId, collateralType, distributor vault. + +**Parameters** +* `poolId` (*uint128*) - The id of the pool being queried. +* `collateralType` (*address*) - The address of the collateral used in the pool's rewards. +* `distributor` (*address*) - The address of the rewards distributor associated with the rewards in question. + +**Returns** +* `rateD18` (*uint256*) - The queried rewards rate. + +#### RewardsDistributed + + ```solidity + event RewardsDistributed(uint128 poolId, address collateralType, address distributor, uint256 amount, uint256 start, uint256 duration) + ``` + + Emitted when the pool owner or an existing reward distributor sets up rewards for vault participants. + +**Parameters** +* `poolId` (*uint128*) - The id of the pool on which rewards were distributed. +* `collateralType` (*address*) - The collateral type of the pool on which rewards were distributed. +* `distributor` (*address*) - The reward distributor associated to the rewards that were distributed. +* `amount` (*uint256*) - The amount of rewards that were distributed. +* `start` (*uint256*) - The date one which the rewards will begin to be claimable. +* `duration` (*uint256*) - The time in which all of the distributed rewards will be claimable. + +#### RewardsClaimed + + ```solidity + event RewardsClaimed(uint128 accountId, uint128 poolId, address collateralType, address distributor, uint256 amount) + ``` + + Emitted when a vault participant claims rewards. + +**Parameters** +* `accountId` (*uint128*) - The id of the account that claimed the rewards. +* `poolId` (*uint128*) - The id of the pool where the rewards were claimed. +* `collateralType` (*address*) - The address of the collateral used in the pool's rewards. +* `distributor` (*address*) - The address of the rewards distributor associated with these rewards. +* `amount` (*uint256*) - The amount of rewards that were claimed. + +#### RewardsDistributorRegistered + + ```solidity + event RewardsDistributorRegistered(uint128 poolId, address collateralType, address distributor) + ``` + + Emitted when a new rewards distributor is registered. + +**Parameters** +* `poolId` (*uint128*) - The id of the pool whose reward distributor was registered. +* `collateralType` (*address*) - The address of the collateral used in the pool's rewards. +* `distributor` (*address*) - The address of the newly registered reward distributor. + +#### RewardsDistributorRemoved + + ```solidity + event RewardsDistributorRemoved(uint128 poolId, address collateralType, address distributor) + ``` + + Emitted when an already registered rewards distributor is removed. + +**Parameters** +* `poolId` (*uint128*) - The id of the pool whose reward distributor was registered. +* `collateralType` (*address*) - The address of the collateral used in the pool's rewards. +* `distributor` (*address*) - The address of the registered reward distributor. + +### USD Token Module + +#### burnWithAllowance + + ```solidity + function burnWithAllowance(address from, address spender, uint256 amount) external + ``` + + Allows the core system to burn snxUSD held by the `from` address, provided that it has given allowance to `spender`. + +**Parameters** +* `from` (*address*) - The address that holds the snxUSD to be burned. +* `spender` (*address*) - The address to which the holder has given allowance to. +* `amount` (*uint256*) - The amount of snxUSD to be burned, denominated with 18 decimals of precision. + +#### burn + + ```solidity + function burn(uint256 amount) external + ``` + + Destroys `amount` of snxUSD tokens from the caller. This is derived from ERC20Burnable.sol and is currently included for testing purposes with CCIP token pools. + +**Parameters** +* `amount` (*uint256*) - The amount of snxUSD to be burned, denominated with 18 decimals of precision. + +#### isInitialized + + ```solidity + function isInitialized() external returns (bool) + ``` + + Returns wether the token has been initialized. + +**Returns** +* `[0]` (*bool*) - A boolean with the result of the query. +#### initialize + + ```solidity + function initialize(string tokenName, string tokenSymbol, uint8 tokenDecimals) external + ``` + + Initializes the token with name, symbol, and decimals. + +#### mint + + ```solidity + function mint(address to, uint256 amount) external + ``` + + Allows the owner to mint tokens. + +**Parameters** +* `to` (*address*) - The address to receive the newly minted tokens. +* `amount` (*uint256*) - The amount of tokens to mint. + +#### burn + + ```solidity + function burn(address from, uint256 amount) external + ``` + + Allows the owner to burn tokens. + +**Parameters** +* `from` (*address*) - The address whose tokens will be burnt. +* `amount` (*uint256*) - The amount of tokens to burn. + +#### setAllowance + + ```solidity + function setAllowance(address from, address spender, uint256 amount) external + ``` + + Allows an address that holds tokens to provide allowance to another. + +**Parameters** +* `from` (*address*) - The address that is providing allowance. +* `spender` (*address*) - The address that is given allowance. +* `amount` (*uint256*) - The amount of allowance being given. + +#### name + + ```solidity + function name() external view returns (string) + ``` + + Retrieves the name of the token, e.g. "Synthetix Network Token". + +**Returns** +* `[0]` (*string*) - A string with the name of the token. +#### symbol + + ```solidity + function symbol() external view returns (string) + ``` + + Retrieves the symbol of the token, e.g. "SNX". + +**Returns** +* `[0]` (*string*) - A string with the symbol of the token. +#### decimals + + ```solidity + function decimals() external view returns (uint8) + ``` + + Retrieves the number of decimals used by the token. The default is 18. + +**Returns** +* `[0]` (*uint8*) - The number of decimals. +#### totalSupply + + ```solidity + function totalSupply() external view returns (uint256) + ``` + + Returns the total number of tokens in circulation (minted - burnt). + +**Returns** +* `[0]` (*uint256*) - The total number of tokens. +#### balanceOf + + ```solidity + function balanceOf(address owner) external view returns (uint256) + ``` + + Returns the balance of a user. + +**Parameters** +* `owner` (*address*) - The address whose balance is being retrieved. + +**Returns** +* `[0]` (*uint256*) - The number of tokens owned by the user. +#### allowance + + ```solidity + function allowance(address owner, address spender) external view returns (uint256) + ``` + + Returns how many tokens a user has allowed another user to transfer on its behalf. + +**Parameters** +* `owner` (*address*) - The user who has given the allowance. +* `spender` (*address*) - The user who was given the allowance. + +**Returns** +* `[0]` (*uint256*) - The amount of tokens `spender` can transfer on `owner`'s behalf. +#### transfer + + ```solidity + function transfer(address to, uint256 amount) external returns (bool) + ``` + + Transfer tokens from one address to another. + +**Parameters** +* `to` (*address*) - The address that will receive the tokens. +* `amount` (*uint256*) - The amount of tokens to be transferred. + +**Returns** +* `[0]` (*bool*) - A boolean which is true if the operation succeeded. +#### approve + + ```solidity + function approve(address spender, uint256 amount) external returns (bool) + ``` + + Allows users to provide allowance to other users so that they can transfer tokens on their behalf. + +**Parameters** +* `spender` (*address*) - The address that is receiving the allowance. +* `amount` (*uint256*) - The amount of tokens that are being added to the allowance. + +**Returns** +* `[0]` (*bool*) - A boolean which is true if the operation succeeded. +#### increaseAllowance + + ```solidity + function increaseAllowance(address spender, uint256 addedValue) external returns (bool) + ``` + + Atomically increases the allowance granted to `spender` by the caller. + +This is an alternative to {approve} that can be used as a mitigation for +problems described in {IERC20-approve}. + +Emits an {Approval} event indicating the updated allowance. + +Requirements: + +- `spender` cannot be the zero address. + +#### decreaseAllowance + + ```solidity + function decreaseAllowance(address spender, uint256 subtractedValue) external returns (bool) + ``` + + Atomically decreases the allowance granted to `spender` by the caller. + +This is an alternative to {approve} that can be used as a mitigation for +problems described in {IERC20-approve}. + +Emits an {Approval} event indicating the updated allowance. + +Requirements: + +- `spender` cannot be the zero address. +- `spender` must have allowance for the caller of at least +`subtractedValue`. + +#### transferFrom + + ```solidity + function transferFrom(address from, address to, uint256 amount) external returns (bool) + ``` + + Allows a user who has been given allowance to transfer tokens on another user's behalf. + +**Parameters** +* `from` (*address*) - The address that owns the tokens that are being transferred. +* `to` (*address*) - The address that will receive the tokens. +* `amount` (*uint256*) - The number of tokens to transfer. + +**Returns** +* `[0]` (*bool*) - A boolean which is true if the operation succeeded. + +#### Transfer + + ```solidity + event Transfer(address from, address to, uint256 amount) + ``` + + Emitted when tokens have been transferred. + +**Parameters** +* `from` (*address*) - The address that originally owned the tokens. +* `to` (*address*) - The address that received the tokens. +* `amount` (*uint256*) - The number of tokens that were transferred. + +#### Approval + + ```solidity + event Approval(address owner, address spender, uint256 amount) + ``` + + Emitted when a user has provided allowance to another user for transferring tokens on its behalf. + +**Parameters** +* `owner` (*address*) - The address that is providing the allowance. +* `spender` (*address*) - The address that received the allowance. +* `amount` (*uint256*) - The number of tokens that were added to `spender`'s allowance. + +### Vault Module + +#### delegateCollateral + + ```solidity + function delegateCollateral(uint128 accountId, uint128 poolId, address collateralType, uint256 amount, uint256 leverage) external + ``` + + Updates an account's delegated collateral amount for the specified pool and collateral type pair. + +**Parameters** +* `accountId` (*uint128*) - The id of the account associated with the position that will be updated. +* `poolId` (*uint128*) - The id of the pool associated with the position. +* `collateralType` (*address*) - The address of the collateral used in the position. +* `amount` (*uint256*) - The new amount of collateral delegated in the position, denominated with 18 decimals of precision. +* `leverage` (*uint256*) - The new leverage amount used in the position, denominated with 18 decimals of precision. Requirements: - `msg.sender` must be the owner of the account, have the `ADMIN` permission, or have the `DELEGATE` permission. - If increasing the amount delegated, it must not exceed the available collateral (`getAccountAvailableCollateral`) associated with the account. - If decreasing the amount delegated, the liquidity position must have a collateralization ratio greater than the target collateralization ratio for the corresponding collateral type. Emits a {DelegationUpdated} event. + +#### getPositionCollateralRatio + + ```solidity + function getPositionCollateralRatio(uint128 accountId, uint128 poolId, address collateralType) external returns (uint256 ratioD18) + ``` + + Returns the collateralization ratio of the specified liquidity position. If debt is negative, this function will return 0. + + Call this function using `callStatic` to treat it as a view function. +The return value is a percentage with 18 decimals places. + +**Parameters** +* `accountId` (*uint128*) - The id of the account whose collateralization ratio is being queried. +* `poolId` (*uint128*) - The id of the pool in which the account's position is held. +* `collateralType` (*address*) - The address of the collateral used in the queried position. + +**Returns** +* `ratioD18` (*uint256*) - The collateralization ratio of the position (collateral / debt), denominated with 18 decimals of precision. +#### getPositionDebt + + ```solidity + function getPositionDebt(uint128 accountId, uint128 poolId, address collateralType) external returns (int256 debtD18) + ``` + + Returns the debt of the specified liquidity position. Credit is expressed as negative debt. + + This is not a view function, and actually updates the entire debt distribution chain. +Call this function using `callStatic` to treat it as a view function. + +**Parameters** +* `accountId` (*uint128*) - The id of the account being queried. +* `poolId` (*uint128*) - The id of the pool in which the account's position is held. +* `collateralType` (*address*) - The address of the collateral used in the queried position. + +**Returns** +* `debtD18` (*int256*) - The amount of debt held by the position, denominated with 18 decimals of precision. +#### getPositionCollateral + + ```solidity + function getPositionCollateral(uint128 accountId, uint128 poolId, address collateralType) external view returns (uint256 collateralAmountD18, uint256 collateralValueD18) + ``` + + Returns the amount and value of the collateral associated with the specified liquidity position. + + Call this function using `callStatic` to treat it as a view function. +collateralAmount is represented as an integer with 18 decimals. +collateralValue is represented as an integer with the number of decimals specified by the collateralType. + +**Parameters** +* `accountId` (*uint128*) - The id of the account being queried. +* `poolId` (*uint128*) - The id of the pool in which the account's position is held. +* `collateralType` (*address*) - The address of the collateral used in the queried position. + +**Returns** +* `collateralAmountD18` (*uint256*) - The amount of collateral used in the position, denominated with 18 decimals of precision. +* `collateralValueD18` (*uint256*) - The value of collateral used in the position, denominated with 18 decimals of precision. +#### getPosition + + ```solidity + function getPosition(uint128 accountId, uint128 poolId, address collateralType) external returns (uint256 collateralAmountD18, uint256 collateralValueD18, int256 debtD18, uint256 collateralizationRatioD18) + ``` + + Returns all information pertaining to a specified liquidity position in the vault module. + +**Parameters** +* `accountId` (*uint128*) - The id of the account being queried. +* `poolId` (*uint128*) - The id of the pool in which the account's position is held. +* `collateralType` (*address*) - The address of the collateral used in the queried position. + +**Returns** +* `collateralAmountD18` (*uint256*) - The amount of collateral used in the position, denominated with 18 decimals of precision. +* `collateralValueD18` (*uint256*) - The value of the collateral used in the position, denominated with 18 decimals of precision. +* `debtD18` (*int256*) - The amount of debt held in the position, denominated with 18 decimals of precision. +* `collateralizationRatioD18` (*uint256*) - The collateralization ratio of the position (collateral / debt), denominated with 18 decimals of precision. +#### getVaultDebt + + ```solidity + function getVaultDebt(uint128 poolId, address collateralType) external returns (int256 debtD18) + ``` + + Returns the total debt (or credit) that the vault is responsible for. Credit is expressed as negative debt. + + This is not a view function, and actually updates the entire debt distribution chain. +Call this function using `callStatic` to treat it as a view function. + +**Parameters** +* `poolId` (*uint128*) - The id of the pool that owns the vault whose debt is being queried. +* `collateralType` (*address*) - The address of the collateral of the associated vault. + +**Returns** +* `debtD18` (*int256*) - The overall debt of the vault, denominated with 18 decimals of precision. +#### getVaultCollateral + + ```solidity + function getVaultCollateral(uint128 poolId, address collateralType) external returns (uint256 collateralAmountD18, uint256 collateralValueD18) + ``` + + Returns the amount and value of the collateral held by the vault. + + Call this function using `callStatic` to treat it as a view function. +collateralAmount is represented as an integer with 18 decimals. +collateralValue is represented as an integer with the number of decimals specified by the collateralType. + +**Parameters** +* `poolId` (*uint128*) - The id of the pool that owns the vault whose collateral is being queried. +* `collateralType` (*address*) - The address of the collateral of the associated vault. + +**Returns** +* `collateralAmountD18` (*uint256*) - The collateral amount of the vault, denominated with 18 decimals of precision. +* `collateralValueD18` (*uint256*) - The collateral value of the vault, denominated with 18 decimals of precision. +#### getVaultCollateralRatio + + ```solidity + function getVaultCollateralRatio(uint128 poolId, address collateralType) external returns (uint256 ratioD18) + ``` + + Returns the collateralization ratio of the vault. If debt is negative, this function will return 0. + + Call this function using `callStatic` to treat it as a view function. +The return value is a percentage with 18 decimals places. + +**Parameters** +* `poolId` (*uint128*) - The id of the pool that owns the vault whose collateralization ratio is being queried. +* `collateralType` (*address*) - The address of the collateral of the associated vault. + +**Returns** +* `ratioD18` (*uint256*) - The collateralization ratio of the vault, denominated with 18 decimals of precision. + +#### DelegationUpdated + + ```solidity + event DelegationUpdated(uint128 accountId, uint128 poolId, address collateralType, uint256 amount, uint256 leverage, address sender) + ``` + + Emitted when {sender} updates the delegation of collateral in the specified liquidity position. + +**Parameters** +* `accountId` (*uint128*) - The id of the account whose position was updated. +* `poolId` (*uint128*) - The id of the pool in which the position was updated. +* `collateralType` (*address*) - The address of the collateral associated to the position. +* `amount` (*uint256*) - The new amount of the position, denominated with 18 decimals of precision. +* `leverage` (*uint256*) - The new leverage value of the position, denominated with 18 decimals of precision. +* `sender` (*address*) - The address that triggered the update of the position. + +## Spot Market + +- [Back to TOC](#smart-contracts) + +### Async Order Configuration Module + +#### addSettlementStrategy + + ```solidity + function addSettlementStrategy(uint128 synthMarketId, struct SettlementStrategy.Data strategy) external returns (uint256 strategyId) + ``` + + Adds new settlement strategy to the specified market id. + +**Parameters** +* `synthMarketId` (*uint128*) - Id of the market to associate the strategy with. +* `strategy` (*struct SettlementStrategy.Data*) - Settlement strategy data. see SettlementStrategy.Data struct. + +**Returns** +* `strategyId` (*uint256*) - newly created settlement strategy id. +#### setSettlementStrategyEnabled + + ```solidity + function setSettlementStrategyEnabled(uint128 synthMarketId, uint256 strategyId, bool enabled) external + ``` + + Sets the strategy to enabled or disabled. + + when disabled, the strategy will be invalid for committing of new async orders. + +**Parameters** +* `synthMarketId` (*uint128*) - Id of the market associated with the strategy. +* `strategyId` (*uint256*) - id of the strategy. +* `enabled` (*bool*) - set enabled/disabled. + +#### getSettlementStrategy + + ```solidity + function getSettlementStrategy(uint128 marketId, uint256 strategyId) external view returns (struct SettlementStrategy.Data settlementStrategy) + ``` + + Returns the settlement strategy data for given market/strategy id. + +**Parameters** +* `marketId` (*uint128*) - Id of the market associated with the strategy. +* `strategyId` (*uint256*) - id of the strategy. + +**Returns** +* `settlementStrategy` (*struct SettlementStrategy.Data*) - + +#### SettlementStrategyAdded + + ```solidity + event SettlementStrategyAdded(uint128 synthMarketId, uint256 strategyId) + ``` + + Gets fired when new settlement strategy is added. + +**Parameters** +* `synthMarketId` (*uint128*) - adds settlement strategy to this specific market. +* `strategyId` (*uint256*) - the newly created settlement strategy id. + +#### SettlementStrategyUpdated + + ```solidity + event SettlementStrategyUpdated(uint128 synthMarketId, uint256 strategyId, bool enabled) + ``` + + Gets fired when settlement strategy is enabled/disabled. + + currently only enabled/disabled flag can be updated. + +**Parameters** +* `synthMarketId` (*uint128*) - adds settlement strategy to this specific market. +* `strategyId` (*uint256*) - id of the strategy. +* `enabled` (*bool*) - true/false. + +### Async Order Module + +#### commitOrder + + ```solidity + function commitOrder(uint128 marketId, enum Transaction.Type orderType, uint256 amountProvided, uint256 settlementStrategyId, uint256 minimumSettlementAmount, address referrer) external returns (struct AsyncOrderClaim.Data asyncOrderClaim) + ``` + + Commit an async order via this function + + commitment transfers the amountProvided into the contract and escrows the funds until settlement. + +**Parameters** +* `marketId` (*uint128*) - Id of the market used for the trade. +* `orderType` (*enum Transaction.Type*) - Should send either 2 or 3 which correlates to the transaction type enum defined in Transaction.Type. +* `amountProvided` (*uint256*) - amount of value provided by the user for trade. Should have enough allowance. +* `settlementStrategyId` (*uint256*) - id of the settlement strategy used for trade. +* `minimumSettlementAmount` (*uint256*) - minimum amount of value returned to trader after fees. +* `referrer` (*address*) - Optional address of the referrer, for fee share + +**Returns** +* `asyncOrderClaim` (*struct AsyncOrderClaim.Data*) - claim details (see AsyncOrderClaim.Data struct). +#### cancelOrder + + ```solidity + function cancelOrder(uint128 marketId, uint128 asyncOrderId) external + ``` + + Cancel an async order via this function + + cancellation transfers the amountProvided back to the trader without any fee collection +cancellation can only happen after the settlement time has passed +needs to satisfy commitmentTime + settlementDelay + settlementDuration < block.timestamp + +**Parameters** +* `marketId` (*uint128*) - Id of the market used for the trade. +* `asyncOrderId` (*uint128*) - id of the async order created during commitment. + +#### getAsyncOrderClaim + + ```solidity + function getAsyncOrderClaim(uint128 marketId, uint128 asyncOrderId) external view returns (struct AsyncOrderClaim.Data asyncOrderClaim) + ``` + + Get async order claim details + +**Parameters** +* `marketId` (*uint128*) - Id of the market used for the trade. +* `asyncOrderId` (*uint128*) - id of the async order created during commitment. + +**Returns** +* `asyncOrderClaim` (*struct AsyncOrderClaim.Data*) - claim details (see AsyncOrderClaim.Data struct). + +#### OrderCommitted + + ```solidity + event OrderCommitted(uint128 marketId, enum Transaction.Type orderType, uint256 amountProvided, uint128 asyncOrderId, address sender, address referrer) + ``` + + Gets fired when a new order is committed. + +**Parameters** +* `marketId` (*uint128*) - Id of the market used for the trade. +* `orderType` (*enum Transaction.Type*) - Should send either 2 or 3 which correlates to the transaction type enum defined in Transaction.Type. +* `amountProvided` (*uint256*) - amount of value provided by the user for trade. +* `asyncOrderId` (*uint128*) - id of the async order created (used for settlements). +* `sender` (*address*) - trader address. +* `referrer` (*address*) - Optional address of the referrer, for fee share + +#### OrderCancelled + + ```solidity + event OrderCancelled(uint128 marketId, uint128 asyncOrderId, struct AsyncOrderClaim.Data asyncOrderClaim, address sender) + ``` + + Gets fired when an order is cancelled. + +**Parameters** +* `marketId` (*uint128*) - Id of the market used for the trade. +* `asyncOrderId` (*uint128*) - id of the async order. +* `asyncOrderClaim` (*struct AsyncOrderClaim.Data*) - claim details (see AsyncOrderClaim.Data struct). +* `sender` (*address*) - trader address and also the receiver of the funds. + +### Async Order Settlement Module + +#### settleOrder + + ```solidity + function settleOrder(uint128 marketId, uint128 asyncOrderId) external returns (uint256 finalOrderAmount, struct OrderFees.Data) + ``` + + Settle already created async order via this function + + if the strategy is onchain, the settlement is done similar to an atomic buy except with settlement time +if the strategy is offchain, this function will revert with OffchainLookup error and the client should perform offchain lookup and call the callback specified see: EIP-3668 + +**Parameters** +* `marketId` (*uint128*) - Id of the market used for the trade. +* `asyncOrderId` (*uint128*) - id of the async order created during commitment. + +**Returns** +* `finalOrderAmount` (*uint256*) - amount returned to trader after fees. +* `[1]` (*struct OrderFees.Data*) - OrderFees.Data breakdown of all the fees incurred for the transaction. +#### settlePythOrder + + ```solidity + function settlePythOrder(bytes result, bytes extraData) external payable returns (uint256 finalOrderAmount, struct OrderFees.Data fees) + ``` + + Callback function for Pyth settlement strategy + + This is the selector specified as callback when settlement strategy is pyth offchain. +The data returned from the offchain lookup should be sent as "result" +The extraData is the same as the one sent during the offchain lookup revert error. It is used to retrieve the commitment claim. +this function expects ETH that is passed through to the Pyth contract for the fee it's charging. +To determine the fee, the client should first call getUpdateFee() from Pyth's verifier contract. + +**Parameters** +* `result` (*bytes*) - result returned from the offchain lookup. +* `extraData` (*bytes*) - extra data sent during the offchain lookup revert error. + +**Returns** +* `finalOrderAmount` (*uint256*) - amount returned to trader after fees. +* `fees` (*struct OrderFees.Data*) - breakdown of all the fees incurred for the transaction. + +#### OrderSettled + + ```solidity + event OrderSettled(uint128 marketId, uint128 asyncOrderId, uint256 finalOrderAmount, struct OrderFees.Data fees, uint256 collectedFees, address settler, uint256 price, enum Transaction.Type orderType) + ``` + + Gets fired when an order is settled. + +**Parameters** +* `marketId` (*uint128*) - Id of the market used for the trade. +* `asyncOrderId` (*uint128*) - id of the async order. +* `finalOrderAmount` (*uint256*) - amount returned to trader after fees. +* `fees` (*struct OrderFees.Data*) - breakdown of all the fees incurred for the transaction. +* `collectedFees` (*uint256*) - fees collected by the configured fee collector. +* `settler` (*address*) - address that settled the order. +* `price` (*uint256*) - +* `orderType` (*enum Transaction.Type*) - + +### Atomic Order Module + +#### buyExactIn + + ```solidity + function buyExactIn(uint128 synthMarketId, uint256 amountUsd, uint256 minAmountReceived, address referrer) external returns (uint256 synthAmount, struct OrderFees.Data fees) + ``` + + Initiates a buy trade returning synth for the specified amountUsd. + + Transfers the specified amountUsd, collects fees through configured fee collector, returns synth to the trader. +Leftover fees not collected get deposited into the market manager to improve market PnL. +Uses the buyFeedId configured for the market. + +**Parameters** +* `synthMarketId` (*uint128*) - Id of the market used for the trade. +* `amountUsd` (*uint256*) - Amount of snxUSD trader is providing allowance for the trade. +* `minAmountReceived` (*uint256*) - Min Amount of synth is expected the trader to receive otherwise the transaction will revert. +* `referrer` (*address*) - Optional address of the referrer, for fee share + +**Returns** +* `synthAmount` (*uint256*) - Synth received on the trade based on amount provided by trader. +* `fees` (*struct OrderFees.Data*) - breakdown of all the fees incurred for the transaction. +#### buy + + ```solidity + function buy(uint128 marketId, uint256 usdAmount, uint256 minAmountReceived, address referrer) external returns (uint256 synthAmount, struct OrderFees.Data fees) + ``` + + alias for buyExactIn + +**Parameters** +* `marketId` (*uint128*) - (see buyExactIn) +* `usdAmount` (*uint256*) - (see buyExactIn) +* `minAmountReceived` (*uint256*) - (see buyExactIn) +* `referrer` (*address*) - (see buyExactIn) + +**Returns** +* `synthAmount` (*uint256*) - (see buyExactIn) +* `fees` (*struct OrderFees.Data*) - (see buyExactIn) +#### buyExactOut + + ```solidity + function buyExactOut(uint128 synthMarketId, uint256 synthAmount, uint256 maxUsdAmount, address referrer) external returns (uint256 usdAmountCharged, struct OrderFees.Data fees) + ``` + + user provides the synth amount they'd like to buy, and the function charges the USD amount which includes fees + + the inverse of buyExactIn + +**Parameters** +* `synthMarketId` (*uint128*) - market id value +* `synthAmount` (*uint256*) - the amount of synth the trader wants to buy +* `maxUsdAmount` (*uint256*) - max amount the trader is willing to pay for the specified synth +* `referrer` (*address*) - optional address of the referrer, for fee share + +**Returns** +* `usdAmountCharged` (*uint256*) - amount of USD charged for the trade +* `fees` (*struct OrderFees.Data*) - breakdown of all the fees incurred for the transaction +#### quoteBuyExactIn + + ```solidity + function quoteBuyExactIn(uint128 synthMarketId, uint256 usdAmount) external view returns (uint256 synthAmount, struct OrderFees.Data fees) + ``` + + quote for buyExactIn. same parameters and return values as buyExactIn + +**Parameters** +* `synthMarketId` (*uint128*) - market id value +* `usdAmount` (*uint256*) - amount of USD to use for the trade + +**Returns** +* `synthAmount` (*uint256*) - return amount of synth given the USD amount - fees +* `fees` (*struct OrderFees.Data*) - breakdown of all the quoted fees for the buy txn +#### quoteBuyExactOut + + ```solidity + function quoteBuyExactOut(uint128 synthMarketId, uint256 synthAmount) external view returns (uint256 usdAmountCharged, struct OrderFees.Data) + ``` + + quote for buyExactOut. same parameters and return values as buyExactOut + +**Parameters** +* `synthMarketId` (*uint128*) - market id value +* `synthAmount` (*uint256*) - amount of synth requested + +**Returns** +* `usdAmountCharged` (*uint256*) - USD amount charged for the synth requested - fees +* `[1]` (*struct OrderFees.Data*) - fees breakdown of all the quoted fees for the buy txn +#### sellExactIn + + ```solidity + function sellExactIn(uint128 synthMarketId, uint256 sellAmount, uint256 minAmountReceived, address referrer) external returns (uint256 returnAmount, struct OrderFees.Data fees) + ``` + + Initiates a sell trade returning snxUSD for the specified amount of synth (sellAmount) + + Transfers the specified synth, collects fees through configured fee collector, returns snxUSD to the trader. +Leftover fees not collected get deposited into the market manager to improve market PnL. + +**Parameters** +* `synthMarketId` (*uint128*) - Id of the market used for the trade. +* `sellAmount` (*uint256*) - Amount of synth provided by trader for trade into snxUSD. +* `minAmountReceived` (*uint256*) - Min Amount of snxUSD trader expects to receive for the trade +* `referrer` (*address*) - Optional address of the referrer, for fee share + +**Returns** +* `returnAmount` (*uint256*) - Amount of snxUSD returned to user +* `fees` (*struct OrderFees.Data*) - breakdown of all the fees incurred for the transaction. +#### sellExactOut + + ```solidity + function sellExactOut(uint128 marketId, uint256 usdAmount, uint256 maxSynthAmount, address referrer) external returns (uint256 synthToBurn, struct OrderFees.Data fees) + ``` + + initiates a trade where trader specifies USD amount they'd like to receive + + the inverse of sellExactIn + +**Parameters** +* `marketId` (*uint128*) - synth market id +* `usdAmount` (*uint256*) - amount of USD trader wants to receive +* `maxSynthAmount` (*uint256*) - max amount of synth trader is willing to use to receive the specified USD amount +* `referrer` (*address*) - optional address of the referrer, for fee share + +**Returns** +* `synthToBurn` (*uint256*) - amount of synth charged for the specified usd amount +* `fees` (*struct OrderFees.Data*) - breakdown of all the fees incurred for the transaction +#### sell + + ```solidity + function sell(uint128 marketId, uint256 synthAmount, uint256 minUsdAmount, address referrer) external returns (uint256 usdAmountReceived, struct OrderFees.Data fees) + ``` + + alias for sellExactIn + +**Parameters** +* `marketId` (*uint128*) - (see sellExactIn) +* `synthAmount` (*uint256*) - (see sellExactIn) +* `minUsdAmount` (*uint256*) - (see sellExactIn) +* `referrer` (*address*) - (see sellExactIn) + +**Returns** +* `usdAmountReceived` (*uint256*) - (see sellExactIn) +* `fees` (*struct OrderFees.Data*) - (see sellExactIn) +#### quoteSellExactIn + + ```solidity + function quoteSellExactIn(uint128 marketId, uint256 synthAmount) external view returns (uint256 returnAmount, struct OrderFees.Data fees) + ``` + + quote for sellExactIn + + returns expected USD amount trader would receive for the specified synth amount + +**Parameters** +* `marketId` (*uint128*) - synth market id +* `synthAmount` (*uint256*) - synth amount trader is providing for the trade + +**Returns** +* `returnAmount` (*uint256*) - amount of USD expected back +* `fees` (*struct OrderFees.Data*) - breakdown of all the quoted fees for the txn +#### quoteSellExactOut + + ```solidity + function quoteSellExactOut(uint128 marketId, uint256 usdAmount) external view returns (uint256 synthToBurn, struct OrderFees.Data fees) + ``` + + quote for sellExactOut + + returns expected synth amount expected from trader for the requested USD amount + +**Parameters** +* `marketId` (*uint128*) - synth market id +* `usdAmount` (*uint256*) - USD amount trader wants to receive + +**Returns** +* `synthToBurn` (*uint256*) - amount of synth expected from trader +* `fees` (*struct OrderFees.Data*) - breakdown of all the quoted fees for the txn + +#### SynthBought + + ```solidity + event SynthBought(uint256 synthMarketId, uint256 synthReturned, struct OrderFees.Data fees, uint256 collectedFees, address referrer, uint256 price) + ``` + + Gets fired when buy trade is complete + +**Parameters** +* `synthMarketId` (*uint256*) - Id of the market used for the trade. +* `synthReturned` (*uint256*) - Synth received on the trade based on amount provided by trader. +* `fees` (*struct OrderFees.Data*) - breakdown of all fees incurred for transaction. +* `collectedFees` (*uint256*) - Fees collected by the configured FeeCollector for the market (rest of the fees are deposited to market manager). +* `referrer` (*address*) - Optional address of the referrer, for fee share +* `price` (*uint256*) - + +#### SynthSold + + ```solidity + event SynthSold(uint256 synthMarketId, uint256 amountReturned, struct OrderFees.Data fees, uint256 collectedFees, address referrer, uint256 price) + ``` + + Gets fired when sell trade is complete + +**Parameters** +* `synthMarketId` (*uint256*) - Id of the market used for the trade. +* `amountReturned` (*uint256*) - Amount of snxUSD returned to user based on synth provided by trader. +* `fees` (*struct OrderFees.Data*) - breakdown of all fees incurred for transaction. +* `collectedFees` (*uint256*) - Fees collected by the configured FeeCollector for the market (rest of the fees are deposited to market manager). +* `referrer` (*address*) - Optional address of the referrer, for fee share +* `price` (*uint256*) - + +### Market Configuration Module + +#### getMarketFees + + ```solidity + function getMarketFees(uint128 synthMarketId) external returns (uint256 atomicFixedFee, uint256 asyncFixedFee, int256 wrapFee, int256 unwrapFee) + ``` + + gets the atomic fixed fee for a given market + +**Parameters** +* `synthMarketId` (*uint128*) - Id of the market the fee applies to. + +**Returns** +* `atomicFixedFee` (*uint256*) - fixed fee amount represented in bips with 18 decimals. +* `asyncFixedFee` (*uint256*) - fixed fee amount represented in bips with 18 decimals. +* `wrapFee` (*int256*) - wrapping fee in %, 18 decimals. Can be negative. +* `unwrapFee` (*int256*) - unwrapping fee in %, 18 decimals. Can be negative. +#### setAtomicFixedFee + + ```solidity + function setAtomicFixedFee(uint128 synthMarketId, uint256 atomicFixedFee) external + ``` + + sets the atomic fixed fee for a given market + + only marketOwner can set the fee + +**Parameters** +* `synthMarketId` (*uint128*) - Id of the market the fee applies to. +* `atomicFixedFee` (*uint256*) - fixed fee amount represented in bips with 18 decimals. + +#### setAsyncFixedFee + + ```solidity + function setAsyncFixedFee(uint128 synthMarketId, uint256 asyncFixedFee) external + ``` + + sets the async fixed fee for a given market + + only marketOwner can set the fee + +**Parameters** +* `synthMarketId` (*uint128*) - Id of the market the fee applies to. +* `asyncFixedFee` (*uint256*) - fixed fee amount represented in bips with 18 decimals. + +#### setMarketSkewScale + + ```solidity + function setMarketSkewScale(uint128 synthMarketId, uint256 skewScale) external + ``` + + sets the skew scale for a given market + + only marketOwner can set the skew scale + +**Parameters** +* `synthMarketId` (*uint128*) - Id of the market the skew scale applies to. +* `skewScale` (*uint256*) - max amount of synth which makes the skew 100%. the fee is derived as a % of the max value. 100% premium means outstanding synth == skewScale. + +#### getMarketSkewScale + + ```solidity + function getMarketSkewScale(uint128 synthMarketId) external returns (uint256 skewScale) + ``` + + gets the skew scale for a given market + +**Parameters** +* `synthMarketId` (*uint128*) - Id of the market the skew scale applies to. + +**Returns** +* `skewScale` (*uint256*) - max amount of synth which makes the skew 100%. the fee is derived as a % of the max value. 100% premium means outstanding synth == skewScale. +#### setMarketUtilizationFees + + ```solidity + function setMarketUtilizationFees(uint128 synthMarketId, uint256 utilizationFeeRate) external + ``` + + sets the market utilization fee for a given market + + only marketOwner can set the fee +100% utilization means the fee is 0. 120% utilization means the fee is 20% * this fee rate (in bips). + +**Parameters** +* `synthMarketId` (*uint128*) - Id of the market the utilization fee applies to. +* `utilizationFeeRate` (*uint256*) - the rate is represented in bips with 18 decimals and is the rate at which fee increases based on the % above 100% utilization of the delegated collateral for the market. + +#### getMarketUtilizationFees + + ```solidity + function getMarketUtilizationFees(uint128 synthMarketId) external returns (uint256 utilizationFeeRate) + ``` + + gets the market utilization fee for a given market + + 100% utilization means the fee is 0. 120% utilization means the fee is 20% * this fee rate (in bips). + +**Parameters** +* `synthMarketId` (*uint128*) - Id of the market the utilization fee applies to. + +**Returns** +* `utilizationFeeRate` (*uint256*) - the rate is represented in bips with 18 decimals and is the rate at which fee increases based on the % above 100% utilization of the delegated collateral for the market. +#### setCollateralLeverage + + ```solidity + function setCollateralLeverage(uint128 synthMarketId, uint256 collateralLeverage) external + ``` + + sets the collateral leverage for a given market + + only marketOwner can set the leverage +this leverage value is a value applied to delegated collateral which is compared to outstanding synth to determine utilization of market, and locked amounts + +**Parameters** +* `synthMarketId` (*uint128*) - Id of the market the collateral leverage applies to. +* `collateralLeverage` (*uint256*) - the leverage is represented as % with 18 decimals. 1 = 1x leverage + +#### getCollateralLeverage + + ```solidity + function getCollateralLeverage(uint128 synthMarketId) external returns (uint256 collateralLeverage) + ``` + + gets the collateral leverage for a given market + + this leverage value is a value applied to delegated collateral which is compared to outstanding synth to determine utilization of market, and locked amounts + +**Parameters** +* `synthMarketId` (*uint128*) - Id of the market the collateral leverage applies to. + +**Returns** +* `collateralLeverage` (*uint256*) - the leverage is represented as % with 18 decimals. 1 = 1x leverage +#### setCustomTransactorFees + + ```solidity + function setCustomTransactorFees(uint128 synthMarketId, address transactor, uint256 fixedFeeAmount) external + ``` + + sets the fixed fee for a given market and transactor + + overrides both the atomic and async fixed fees +only marketOwner can set the fee +especially useful for direct integrations where configured traders get a discount + +**Parameters** +* `synthMarketId` (*uint128*) - Id of the market the custom transactor fee applies to. +* `transactor` (*address*) - address of the trader getting discounted fees. +* `fixedFeeAmount` (*uint256*) - the fixed fee applying to the provided transactor. + +#### getCustomTransactorFees + + ```solidity + function getCustomTransactorFees(uint128 synthMarketId, address transactor) external returns (uint256 fixedFeeAmount) + ``` + + gets the fixed fee for a given market and transactor + + overrides both the atomic and async fixed fees +especially useful for direct integrations where configured traders get a discount + +**Parameters** +* `synthMarketId` (*uint128*) - Id of the market the custom transactor fee applies to. +* `transactor` (*address*) - address of the trader getting discounted fees. + +**Returns** +* `fixedFeeAmount` (*uint256*) - the fixed fee applying to the provided transactor. +#### setFeeCollector + + ```solidity + function setFeeCollector(uint128 synthMarketId, address feeCollector) external + ``` + + sets a custom fee collector for a given market + + only marketOwner can set the fee collector +a use case here would be if the market owner wants to collect the fees via this contract and distribute via rewards distributor to SNX holders for example. +if fee collector is not set, the fees are deposited into the market manager. + +**Parameters** +* `synthMarketId` (*uint128*) - Id of the market the fee collector applies to. +* `feeCollector` (*address*) - address of the fee collector inheriting the IFeeCollector interface. + +#### getFeeCollector + + ```solidity + function getFeeCollector(uint128 synthMarketId) external returns (address feeCollector) + ``` + + gets a custom fee collector for a given market + +**Parameters** +* `synthMarketId` (*uint128*) - Id of the market the fee collector applies to. + +**Returns** +* `feeCollector` (*address*) - address of the fee collector inheriting the IFeeCollector interface. +#### setWrapperFees + + ```solidity + function setWrapperFees(uint128 synthMarketId, int256 wrapFee, int256 unwrapFee) external + ``` + + sets wrapper related fees. + + only marketOwner can set the wrapper fees +fees can be negative. this is a way to unwind the wrapper if needed by providing incentives. + +**Parameters** +* `synthMarketId` (*uint128*) - Id of the market the wrapper fees apply to. +* `wrapFee` (*int256*) - wrapping fee in %, 18 decimals. Can be negative. +* `unwrapFee` (*int256*) - unwrapping fee in %, 18 decimals. Can be negative. + +#### updateReferrerShare + + ```solidity + function updateReferrerShare(uint128 marketId, address referrer, uint256 sharePercentage) external + ``` + + Update the referral share percentage for a given market + +**Parameters** +* `marketId` (*uint128*) - id of the market +* `referrer` (*address*) - The address of the referrer +* `sharePercentage` (*uint256*) - The new share percentage for the referrer + +#### getReferrerShare + + ```solidity + function getReferrerShare(uint128 marketId, address referrer) external returns (uint256 sharePercentage) + ``` + + get the referral share percentage for a given market + +**Parameters** +* `marketId` (*uint128*) - id of the market +* `referrer` (*address*) - The address of the referrer + +**Returns** +* `sharePercentage` (*uint256*) - The new share percentage for the referrer + +#### MarketUtilizationFeesSet + + ```solidity + event MarketUtilizationFeesSet(uint256 synthMarketId, uint256 utilizationFeeRate) + ``` + + emitted when market utilization fees are set for specified market + +**Parameters** +* `synthMarketId` (*uint256*) - market id +* `utilizationFeeRate` (*uint256*) - utilization fee rate value + +#### MarketSkewScaleSet + + ```solidity + event MarketSkewScaleSet(uint256 synthMarketId, uint256 skewScale) + ``` + + emitted when the skew scale is set for a market + +**Parameters** +* `synthMarketId` (*uint256*) - market id +* `skewScale` (*uint256*) - skew scale value + +#### CollateralLeverageSet + + ```solidity + event CollateralLeverageSet(uint256 synthMarketId, uint256 collateralLeverage) + ``` + + emitted when the collateral leverage is set for a market + +**Parameters** +* `synthMarketId` (*uint256*) - market id +* `collateralLeverage` (*uint256*) - leverage value + +#### AtomicFixedFeeSet + + ```solidity + event AtomicFixedFeeSet(uint256 synthMarketId, uint256 atomicFixedFee) + ``` + + emitted when the fixed fee for atomic orders is set. + +**Parameters** +* `synthMarketId` (*uint256*) - market id +* `atomicFixedFee` (*uint256*) - fee value + +#### AsyncFixedFeeSet + + ```solidity + event AsyncFixedFeeSet(uint256 synthMarketId, uint256 asyncFixedFee) + ``` + + emitted when the fixed fee for async orders is set. + +**Parameters** +* `synthMarketId` (*uint256*) - market id +* `asyncFixedFee` (*uint256*) - fee value + +#### TransactorFixedFeeSet + + ```solidity + event TransactorFixedFeeSet(uint256 synthMarketId, address transactor, uint256 fixedFeeAmount) + ``` + + emitted when the fixed fee is set for a given transactor + + this overrides the async/atomic fixed fees for a given transactor + +**Parameters** +* `synthMarketId` (*uint256*) - Id of the market to set the fees for. +* `transactor` (*address*) - fixed fee for the transactor (overrides the global fixed fee) +* `fixedFeeAmount` (*uint256*) - the fixed fee for the corresponding market, and transactor + +#### FeeCollectorSet + + ```solidity + event FeeCollectorSet(uint256 synthMarketId, address feeCollector) + ``` + + emitted when custom fee collector is set for a given market + +**Parameters** +* `synthMarketId` (*uint256*) - Id of the market to set the collector for. +* `feeCollector` (*address*) - the address of the fee collector to set. + +#### WrapperFeesSet + + ```solidity + event WrapperFeesSet(uint256 synthMarketId, int256 wrapFee, int256 unwrapFee) + ``` + + emitted when wrapper fees are set for a given market + +**Parameters** +* `synthMarketId` (*uint256*) - Id of the market to set the wrapper fees. +* `wrapFee` (*int256*) - wrapping fee in %, 18 decimals. Can be negative. +* `unwrapFee` (*int256*) - unwrapping fee in %, 18 decimals. Can be negative. + +#### ReferrerShareUpdated + + ```solidity + event ReferrerShareUpdated(uint128 marketId, address referrer, uint256 sharePercentage) + ``` + + Emitted when the share percentage for a referrer address has been updated. + +**Parameters** +* `marketId` (*uint128*) - Id of the market +* `referrer` (*address*) - The address of the referrer +* `sharePercentage` (*uint256*) - The new share percentage for the referrer + +### Spot Market Factory Module + +#### setSynthetix + + ```solidity + function setSynthetix(contract ISynthetixSystem synthetix) external + ``` + + Sets the v3 synthetix core system. + + Pulls in the USDToken and oracle manager from the synthetix core system and sets those appropriately. + +**Parameters** +* `synthetix` (*contract ISynthetixSystem*) - synthetix v3 core system address + +#### setSynthImplementation + + ```solidity + function setSynthImplementation(address synthImplementation) external + ``` + + When a new synth is created, this is the erc20 implementation that is used. + +**Parameters** +* `synthImplementation` (*address*) - erc20 implementation address + +#### createSynth + + ```solidity + function createSynth(string tokenName, string tokenSymbol, address synthOwner) external returns (uint128 synthMarketId) + ``` + + Creates a new synth market with synthetix v3 core system via market manager + + The synth is created using the initial synth implementation and creates a proxy for future upgrades of the synth implementation. +Sets up the market owner who can update configuration for the synth. + +**Parameters** +* `tokenName` (*string*) - name of synth (i.e Synthetix ETH) +* `tokenSymbol` (*string*) - symbol of synth (i.e snxETH) +* `synthOwner` (*address*) - owner of the market that's created. + +**Returns** +* `synthMarketId` (*uint128*) - id of the synth market that was created +#### getSynth + + ```solidity + function getSynth(uint128 marketId) external view returns (address synthAddress) + ``` + + Get the proxy address of the synth for the provided marketId + + Uses associated systems module to retrieve the token address. + +**Parameters** +* `marketId` (*uint128*) - id of the market + +**Returns** +* `synthAddress` (*address*) - address of the proxy for the synth +#### getSynthImpl + + ```solidity + function getSynthImpl(uint128 marketId) external view returns (address implAddress) + ``` + + Get the implementation address of the synth for the provided marketId. +This address should not be used directly--use `getSynth` instead + + Uses associated systems module to retrieve the token address. + +**Parameters** +* `marketId` (*uint128*) - id of the market + +**Returns** +* `implAddress` (*address*) - address of the proxy for the synth +#### updatePriceData + + ```solidity + function updatePriceData(uint128 marketId, bytes32 buyFeedId, bytes32 sellFeedId) external + ``` + + Update the price data for a given market. + + Only the market owner can call this function. + +**Parameters** +* `marketId` (*uint128*) - id of the market +* `buyFeedId` (*bytes32*) - the oracle manager buy feed node id +* `sellFeedId` (*bytes32*) - the oracle manager sell feed node id + +#### upgradeSynthImpl + + ```solidity + function upgradeSynthImpl(uint128 marketId) external + ``` + + upgrades the synth implementation to the current implementation for the specified market. +Anyone who is willing and able to spend the gas can call this method. + + The synth implementation is upgraded via the proxy. + +**Parameters** +* `marketId` (*uint128*) - id of the market + +#### setDecayRate + + ```solidity + function setDecayRate(uint128 marketId, uint256 rate) external + ``` + + Allows market to adjust decay rate of the synth + +**Parameters** +* `marketId` (*uint128*) - the market to update the synth decay rate for +* `rate` (*uint256*) - APY to decay of the synth to decay by, as a 18 decimal ratio + +#### nominateMarketOwner + + ```solidity + function nominateMarketOwner(uint128 synthMarketId, address newNominatedOwner) external + ``` + + Allows the current market owner to nominate a new owner. + + The nominated owner will have to call `acceptOwnership` in a separate transaction in order to finalize the action and become the new contract owner. + +**Parameters** +* `synthMarketId` (*uint128*) - synth market id value +* `newNominatedOwner` (*address*) - The address that is to become nominated. + +#### acceptMarketOwnership + + ```solidity + function acceptMarketOwnership(uint128 synthMarketId) external + ``` + + Allows a nominated address to accept ownership of the market. + + Reverts if the caller is not nominated. + +**Parameters** +* `synthMarketId` (*uint128*) - synth market id value + +#### renounceMarketNomination + + ```solidity + function renounceMarketNomination(uint128 synthMarketId) external + ``` + + Allows a nominated address to renounce ownership of the market. + + Reverts if the caller is not nominated. + +**Parameters** +* `synthMarketId` (*uint128*) - synth market id value + +#### getMarketOwner + + ```solidity + function getMarketOwner(uint128 synthMarketId) external view returns (address) + ``` + + Returns market owner. + +**Parameters** +* `synthMarketId` (*uint128*) - synth market id value + +#### name + + ```solidity + function name(uint128 marketId) external view returns (string) + ``` + + returns a human-readable name for a given market + +#### reportedDebt + + ```solidity + function reportedDebt(uint128 marketId) external view returns (uint256) + ``` + + returns amount of USD that the market would try to mint if everything was withdrawn + +#### minimumCredit + + ```solidity + function minimumCredit(uint128 marketId) external view returns (uint256) + ``` + + prevents reduction of available credit capacity by specifying this amount, for which withdrawals will be disallowed + +#### supportsInterface + + ```solidity + function supportsInterface(bytes4 interfaceID) external view returns (bool) + ``` + + Determines if the contract in question supports the specified interface. + +**Parameters** +* `interfaceID` (*bytes4*) - XOR of all selectors in the contract. + +**Returns** +* `[0]` (*bool*) - True if the contract supports the specified interface. + +#### SynthetixSystemSet + + ```solidity + event SynthetixSystemSet(address synthetix, address usdTokenAddress, address oracleManager) + ``` + + Gets fired when the synthetix is set + +**Parameters** +* `synthetix` (*address*) - address of the synthetix core contract +* `usdTokenAddress` (*address*) - address of the USDToken contract +* `oracleManager` (*address*) - address of the Oracle Manager contract + +#### SynthImplementationSet + + ```solidity + event SynthImplementationSet(address synthImplementation) + ``` + + Gets fired when the synth implementation is set + +**Parameters** +* `synthImplementation` (*address*) - address of the synth implementation + +#### SynthRegistered + + ```solidity + event SynthRegistered(uint256 synthMarketId) + ``` + + Gets fired when the synth is registered as a market. + +**Parameters** +* `synthMarketId` (*uint256*) - Id of the synth market that was created + +#### SynthImplementationUpgraded + + ```solidity + event SynthImplementationUpgraded(uint256 synthMarketId, address proxy, address implementation) + ``` + + Gets fired when the synth's implementation is updated on the corresponding proxy. + +**Parameters** +* `synthMarketId` (*uint256*) - +* `proxy` (*address*) - the synth proxy servicing the latest implementation +* `implementation` (*address*) - the latest implementation of the synth + +#### SynthPriceDataUpdated + + ```solidity + event SynthPriceDataUpdated(uint256 synthMarketId, bytes32 buyFeedId, bytes32 sellFeedId) + ``` + + Gets fired when the market's price feeds are updated, compatible with oracle manager + +**Parameters** +* `synthMarketId` (*uint256*) - +* `buyFeedId` (*bytes32*) - the oracle manager feed id for the buy price +* `sellFeedId` (*bytes32*) - the oracle manager feed id for the sell price + +#### DecayRateUpdated + + ```solidity + event DecayRateUpdated(uint128 marketId, uint256 rate) + ``` + + Gets fired when the market's price feeds are updated, compatible with oracle manager + +**Parameters** +* `marketId` (*uint128*) - Id of the synth market +* `rate` (*uint256*) - the new decay rate (1e16 means 1% decay per year) + +#### MarketOwnerNominated + + ```solidity + event MarketOwnerNominated(uint128 marketId, address newOwner) + ``` + + Emitted when an address has been nominated. + +**Parameters** +* `marketId` (*uint128*) - id of the market +* `newOwner` (*address*) - The address that has been nominated. + +#### MarketNominationRenounced + + ```solidity + event MarketNominationRenounced(uint128 marketId, address nominee) + ``` + + Emitted when market nominee renounces nomination. + +**Parameters** +* `marketId` (*uint128*) - id of the market +* `nominee` (*address*) - The address that has been nominated. + +#### MarketOwnerChanged + + ```solidity + event MarketOwnerChanged(uint128 marketId, address oldOwner, address newOwner) + ``` + + Emitted when the owner of the market has changed. + +**Parameters** +* `marketId` (*uint128*) - id of the market +* `oldOwner` (*address*) - The previous owner of the market. +* `newOwner` (*address*) - The new owner of the market. + +### Synth Token Module + +#### setDecayRate + + ```solidity + function setDecayRate(uint256 _rate) external + ``` + + Updates the decay rate for a year + +**Parameters** +* `_rate` (*uint256*) - The decay rate with 18 decimals (1e16 means 1% decay per year). + +#### decayRate + + ```solidity + function decayRate() external returns (uint256) + ``` + + get decay rate for a year + +#### advanceEpoch + + ```solidity + function advanceEpoch() external returns (uint256) + ``` + + advance epoch manually in order to avoid precision loss + +#### isInitialized + + ```solidity + function isInitialized() external returns (bool) + ``` + + Returns wether the token has been initialized. + +**Returns** +* `[0]` (*bool*) - A boolean with the result of the query. +#### initialize + + ```solidity + function initialize(string tokenName, string tokenSymbol, uint8 tokenDecimals) external + ``` + + Initializes the token with name, symbol, and decimals. + +#### mint + + ```solidity + function mint(address to, uint256 amount) external + ``` + + Allows the owner to mint tokens. + +**Parameters** +* `to` (*address*) - The address to receive the newly minted tokens. +* `amount` (*uint256*) - The amount of tokens to mint. + +#### burn + + ```solidity + function burn(address from, uint256 amount) external + ``` + + Allows the owner to burn tokens. + +**Parameters** +* `from` (*address*) - The address whose tokens will be burnt. +* `amount` (*uint256*) - The amount of tokens to burn. + +#### setAllowance + + ```solidity + function setAllowance(address from, address spender, uint256 amount) external + ``` + + Allows an address that holds tokens to provide allowance to another. + +**Parameters** +* `from` (*address*) - The address that is providing allowance. +* `spender` (*address*) - The address that is given allowance. +* `amount` (*uint256*) - The amount of allowance being given. + +#### name + + ```solidity + function name() external view returns (string) + ``` + + Retrieves the name of the token, e.g. "Synthetix Network Token". + +**Returns** +* `[0]` (*string*) - A string with the name of the token. +#### symbol + + ```solidity + function symbol() external view returns (string) + ``` + + Retrieves the symbol of the token, e.g. "SNX". + +**Returns** +* `[0]` (*string*) - A string with the symbol of the token. +#### decimals + + ```solidity + function decimals() external view returns (uint8) + ``` + + Retrieves the number of decimals used by the token. The default is 18. + +**Returns** +* `[0]` (*uint8*) - The number of decimals. +#### totalSupply + + ```solidity + function totalSupply() external view returns (uint256) + ``` + + Returns the total number of tokens in circulation (minted - burnt). + +**Returns** +* `[0]` (*uint256*) - The total number of tokens. +#### balanceOf + + ```solidity + function balanceOf(address owner) external view returns (uint256) + ``` + + Returns the balance of a user. + +**Parameters** +* `owner` (*address*) - The address whose balance is being retrieved. + +**Returns** +* `[0]` (*uint256*) - The number of tokens owned by the user. +#### allowance + + ```solidity + function allowance(address owner, address spender) external view returns (uint256) + ``` + + Returns how many tokens a user has allowed another user to transfer on its behalf. + +**Parameters** +* `owner` (*address*) - The user who has given the allowance. +* `spender` (*address*) - The user who was given the allowance. + +**Returns** +* `[0]` (*uint256*) - The amount of tokens `spender` can transfer on `owner`'s behalf. +#### transfer + + ```solidity + function transfer(address to, uint256 amount) external returns (bool) + ``` + + Transfer tokens from one address to another. + +**Parameters** +* `to` (*address*) - The address that will receive the tokens. +* `amount` (*uint256*) - The amount of tokens to be transferred. + +**Returns** +* `[0]` (*bool*) - A boolean which is true if the operation succeeded. +#### approve + + ```solidity + function approve(address spender, uint256 amount) external returns (bool) + ``` + + Allows users to provide allowance to other users so that they can transfer tokens on their behalf. + +**Parameters** +* `spender` (*address*) - The address that is receiving the allowance. +* `amount` (*uint256*) - The amount of tokens that are being added to the allowance. + +**Returns** +* `[0]` (*bool*) - A boolean which is true if the operation succeeded. +#### increaseAllowance + + ```solidity + function increaseAllowance(address spender, uint256 addedValue) external returns (bool) + ``` + + Atomically increases the allowance granted to `spender` by the caller. + +This is an alternative to {approve} that can be used as a mitigation for +problems described in {IERC20-approve}. + +Emits an {Approval} event indicating the updated allowance. + +Requirements: + +- `spender` cannot be the zero address. + +#### decreaseAllowance + + ```solidity + function decreaseAllowance(address spender, uint256 subtractedValue) external returns (bool) + ``` + + Atomically decreases the allowance granted to `spender` by the caller. + +This is an alternative to {approve} that can be used as a mitigation for +problems described in {IERC20-approve}. + +Emits an {Approval} event indicating the updated allowance. + +Requirements: + +- `spender` cannot be the zero address. +- `spender` must have allowance for the caller of at least +`subtractedValue`. + +#### transferFrom + + ```solidity + function transferFrom(address from, address to, uint256 amount) external returns (bool) + ``` + + Allows a user who has been given allowance to transfer tokens on another user's behalf. + +**Parameters** +* `from` (*address*) - The address that owns the tokens that are being transferred. +* `to` (*address*) - The address that will receive the tokens. +* `amount` (*uint256*) - The number of tokens to transfer. + +**Returns** +* `[0]` (*bool*) - A boolean which is true if the operation succeeded. + +#### Transfer + + ```solidity + event Transfer(address from, address to, uint256 amount) + ``` + + Emitted when tokens have been transferred. + +**Parameters** +* `from` (*address*) - The address that originally owned the tokens. +* `to` (*address*) - The address that received the tokens. +* `amount` (*uint256*) - The number of tokens that were transferred. + +#### Approval + + ```solidity + event Approval(address owner, address spender, uint256 amount) + ``` + + Emitted when a user has provided allowance to another user for transferring tokens on its behalf. + +**Parameters** +* `owner` (*address*) - The address that is providing the allowance. +* `spender` (*address*) - The address that received the allowance. +* `amount` (*uint256*) - The number of tokens that were added to `spender`'s allowance. + +### Wrapper Module + +#### setWrapper + + ```solidity + function setWrapper(uint128 marketId, address wrapCollateralType, uint256 maxWrappableAmount) external + ``` + + Used to set the wrapper supply cap for a given market and collateral type. + + If the supply cap is set to 0 or lower than the current outstanding supply, then the wrapper is disabled. +There is a synthetix v3 core system supply cap also set. If the current supply becomes higher than either the core system supply cap or the local market supply cap, wrapping will be disabled. + +**Parameters** +* `marketId` (*uint128*) - Id of the market to enable wrapping for. +* `wrapCollateralType` (*address*) - The collateral being used to wrap the synth. +* `maxWrappableAmount` (*uint256*) - The maximum amount of collateral that can be wrapped. + +#### wrap + + ```solidity + function wrap(uint128 marketId, uint256 wrapAmount, uint256 minAmountReceived) external returns (uint256 amountToMint, struct OrderFees.Data fees) + ``` + + Wraps the specified amount and returns similar value of synth minus the fees. + + Fees are collected from the user by way of the contract returning less synth than specified amount of collateral. + +**Parameters** +* `marketId` (*uint128*) - Id of the market used for the trade. +* `wrapAmount` (*uint256*) - Amount of collateral to wrap. This amount gets deposited into the market collateral manager. +* `minAmountReceived` (*uint256*) - The minimum amount of synths the trader is expected to receive, otherwise the transaction will revert. + +**Returns** +* `amountToMint` (*uint256*) - Amount of synth returned to user. +* `fees` (*struct OrderFees.Data*) - breakdown of all fees. in this case, only wrapper fees are returned. +#### unwrap + + ```solidity + function unwrap(uint128 marketId, uint256 unwrapAmount, uint256 minAmountReceived) external returns (uint256 returnCollateralAmount, struct OrderFees.Data fees) + ``` + + Unwraps the synth and returns similar value of collateral minus the fees. + + Transfers the specified synth, collects fees through configured fee collector, returns collateral minus fees to trader. + +**Parameters** +* `marketId` (*uint128*) - Id of the market used for the trade. +* `unwrapAmount` (*uint256*) - Amount of synth trader is unwrapping. +* `minAmountReceived` (*uint256*) - The minimum amount of collateral the trader is expected to receive, otherwise the transaction will revert. + +**Returns** +* `returnCollateralAmount` (*uint256*) - Amount of collateral returned. +* `fees` (*struct OrderFees.Data*) - breakdown of all fees. in this case, only wrapper fees are returned. + +#### WrapperSet + + ```solidity + event WrapperSet(uint256 synthMarketId, address wrapCollateralType, uint256 maxWrappableAmount) + ``` + + Gets fired when wrapper supply is set for a given market, collateral type. + +**Parameters** +* `synthMarketId` (*uint256*) - Id of the market the wrapper is initialized for. +* `wrapCollateralType` (*address*) - the collateral used to wrap the synth. +* `maxWrappableAmount` (*uint256*) - the local supply cap for the wrapper. + +#### SynthWrapped + + ```solidity + event SynthWrapped(uint256 synthMarketId, uint256 amountWrapped, struct OrderFees.Data fees, uint256 feesCollected) + ``` + + Gets fired after user wraps synth + +**Parameters** +* `synthMarketId` (*uint256*) - Id of the market. +* `amountWrapped` (*uint256*) - amount of synth wrapped. +* `fees` (*struct OrderFees.Data*) - breakdown of all the fees incurred for the transaction. +* `feesCollected` (*uint256*) - fees collected by the configured FeeCollector for the market (rest of the fees are deposited to market manager). + +#### SynthUnwrapped + + ```solidity + event SynthUnwrapped(uint256 synthMarketId, uint256 amountUnwrapped, struct OrderFees.Data fees, uint256 feesCollected) + ``` + + Gets fired after user unwraps synth + +**Parameters** +* `synthMarketId` (*uint256*) - Id of the market. +* `amountUnwrapped` (*uint256*) - amount of synth unwrapped. +* `fees` (*struct OrderFees.Data*) - breakdown of all the fees incurred for the transaction. +* `feesCollected` (*uint256*) - fees collected by the configured FeeCollector for the market (rest of the fees are deposited to market manager). + +## Perps Market + +- [Back to TOC](#smart-contracts) + +### Async Order Module + +#### commitOrder + + ```solidity + function commitOrder(struct AsyncOrder.OrderCommitmentRequest commitment) external returns (struct AsyncOrder.Data retOrder, uint256 fees) + ``` + + Commit an async order via this function + +**Parameters** +* `commitment` (*struct AsyncOrder.OrderCommitmentRequest*) - Order commitment data (see AsyncOrder.OrderCommitmentRequest struct). + +**Returns** +* `retOrder` (*struct AsyncOrder.Data*) - order details (see AsyncOrder.Data struct). +* `fees` (*uint256*) - order fees (protocol + settler) +#### getOrder + + ```solidity + function getOrder(uint128 accountId) external returns (struct AsyncOrder.Data order) + ``` + + Get async order claim details + +**Parameters** +* `accountId` (*uint128*) - id of the account. + +**Returns** +* `order` (*struct AsyncOrder.Data*) - async order claim details (see AsyncOrder.Data struct). +#### computeOrderFees + + ```solidity + function computeOrderFees(uint128 marketId, int128 sizeDelta) external view returns (uint256 orderFees) + ``` + + Simulates what the order fee would be for the given market with the specified size. + + Note that this does not include the settlement reward fee, which is based on the strategy type used + +**Parameters** +* `marketId` (*uint128*) - id of the market. +* `sizeDelta` (*int128*) - size of position. + +**Returns** +* `orderFees` (*uint256*) - incurred fees. + +#### OrderCommitted + + ```solidity + event OrderCommitted(uint128 marketId, uint128 accountId, enum SettlementStrategy.Type orderType, int128 sizeDelta, uint256 acceptablePrice, uint256 settlementTime, uint256 expirationTime, bytes32 trackingCode, address sender) + ``` + + Gets fired when a new order is committed. + +**Parameters** +* `marketId` (*uint128*) - Id of the market used for the trade. +* `accountId` (*uint128*) - Id of the account used for the trade. +* `orderType` (*enum SettlementStrategy.Type*) - Should send 0 (at time of writing) that correlates to the transaction type enum defined in SettlementStrategy.Type. +* `sizeDelta` (*int128*) - requested change in size of the order sent by the user. +* `acceptablePrice` (*uint256*) - maximum or minimum, depending on the sizeDelta direction, accepted price to settle the order, set by the user. +* `settlementTime` (*uint256*) - Time at which the order can be settled. +* `expirationTime` (*uint256*) - Time at which the order expired. +* `trackingCode` (*bytes32*) - Optional code for integrator tracking purposes. +* `sender` (*address*) - address of the sender of the order. Authorized to commit by account owner. + +### Async Order Settlement Module + +#### settle + + ```solidity + function settle(uint128 accountId) external view + ``` + + Settles an offchain order. It's expected to revert with the OffchainLookup error with the data needed to perform the offchain lookup. + +**Parameters** +* `accountId` (*uint128*) - Id of the account used for the trade. + +#### settlePythOrder + + ```solidity + function settlePythOrder(bytes result, bytes extraData) external payable + ``` + + Settles an offchain order using the offchain retrieved data from pyth. + +**Parameters** +* `result` (*bytes*) - the blob of data retrieved offchain. +* `extraData` (*bytes*) - Extra data from OffchainLookupData. + +#### OrderSettled + + ```solidity + event OrderSettled(uint128 marketId, uint128 accountId, uint256 fillPrice, int256 pnl, int128 sizeDelta, int128 newSize, uint256 totalFees, uint256 referralFees, uint256 collectedFees, uint256 settlementReward, bytes32 trackingCode, address settler) + ``` + + Gets fired when a new order is settled. + +**Parameters** +* `marketId` (*uint128*) - Id of the market used for the trade. +* `accountId` (*uint128*) - Id of the account used for the trade. +* `fillPrice` (*uint256*) - Price at which the order was settled. +* `pnl` (*int256*) - +* `sizeDelta` (*int128*) - Size delta from order. +* `newSize` (*int128*) - New size of the position after settlement. +* `totalFees` (*uint256*) - Amount of fees collected by the protocol. +* `referralFees` (*uint256*) - Amount of fees collected by the referrer. +* `collectedFees` (*uint256*) - Amount of fees collected by fee collector. +* `settlementReward` (*uint256*) - Amount of fees collected by the settler. +* `trackingCode` (*bytes32*) - Optional code for integrator tracking purposes. +* `settler` (*address*) - address of the settler of the order. + +### Collateral Module + +#### setMaxCollateralAmount + + ```solidity + function setMaxCollateralAmount(uint128 synthMarketId, uint256 collateralAmount) external + ``` + + Set the max collateral amoutn via this function + +**Parameters** +* `synthMarketId` (*uint128*) - Synth market id, 0 for snxUSD. +* `collateralAmount` (*uint256*) - max amount that for the synth + +#### MaxCollateralSet + + ```solidity + event MaxCollateralSet(uint128 synthMarketId, uint256 collateralAmount) + ``` + + Gets fired when max collateral amount for synth collateral for the system is set by owner. + +**Parameters** +* `synthMarketId` (*uint128*) - Synth market id, 0 for snxUSD. +* `collateralAmount` (*uint256*) - max amount that was set for the synth + +### Global Perps Market Module + +#### setMaxCollateralAmount + + ```solidity + function setMaxCollateralAmount(uint128 synthMarketId, uint256 collateralAmount) external + ``` + + Sets the max collateral amount for a specific synth market. + +**Parameters** +* `synthMarketId` (*uint128*) - Synth market id, 0 for snxUSD. +* `collateralAmount` (*uint256*) - Max collateral amount to set for the synth market id. + +#### getMaxCollateralAmount + + ```solidity + function getMaxCollateralAmount(uint128 synthMarketId) external view returns (uint256) + ``` + + Gets the max collateral amount for a specific synth market. + +**Parameters** +* `synthMarketId` (*uint128*) - Synth market id, 0 for snxUSD. + +**Returns** +* `[0]` (*uint256*) - maxCollateralAmount max collateral amount of the specified synth market id +#### setSynthDeductionPriority + + ```solidity + function setSynthDeductionPriority(uint128[] newSynthDeductionPriority) external + ``` + + Sets the synth deduction priority ordered list. + + The synth deduction priority is used to determine the order in which synths are deducted from an account. Id 0 is snxUSD and should be first in the list. + +**Parameters** +* `newSynthDeductionPriority` (*uint128[]*) - Ordered array of synth market ids for deduction priority. + +#### getSynthDeductionPriority + + ```solidity + function getSynthDeductionPriority() external view returns (uint128[]) + ``` + + Gets the synth deduction priority ordered list. + + The synth deduction priority is used to determine the order in which synths are deducted from an account. Id 0 is snxUSD and should be first in the list. + +**Returns** +* `[0]` (*uint128[]*) - synthDeductionPriority Ordered array of synth market ids for deduction priority. +#### setLiquidationRewardGuards + + ```solidity + function setLiquidationRewardGuards(uint256 minLiquidationRewardUsd, uint256 maxLiquidationRewardUsd) external + ``` + + Sets the liquidation reward guard (min and max). + +**Parameters** +* `minLiquidationRewardUsd` (*uint256*) - Minimum liquidation reward expressed as USD value. +* `maxLiquidationRewardUsd` (*uint256*) - Maximum liquidation reward expressed as USD value. + +#### getLiquidationRewardGuards + + ```solidity + function getLiquidationRewardGuards() external view returns (uint256 minLiquidationRewardUsd, uint256 maxLiquidationRewardUsd) + ``` + + Gets the liquidation reward guard (min and max). + +**Returns** +* `minLiquidationRewardUsd` (*uint256*) - Minimum liquidation reward expressed as USD value. +* `maxLiquidationRewardUsd` (*uint256*) - Maximum liquidation reward expressed as USD value. +#### totalGlobalCollateralValue + + ```solidity + function totalGlobalCollateralValue() external view returns (uint256 totalCollateralValue) + ``` + + Gets the total collateral value of all deposited collateral from all traders. + +**Returns** +* `totalCollateralValue` (*uint256*) - value of all collateral +#### setFeeCollector + + ```solidity + function setFeeCollector(address feeCollector) external + ``` + + Sets the fee collector contract. + + must conform to the IFeeCollector interface + +**Parameters** +* `feeCollector` (*address*) - address of the fee collector contract + +#### getFeeCollector + + ```solidity + function getFeeCollector() external view returns (address feeCollector) + ``` + + Gets the configured feeCollector contract + +**Returns** +* `feeCollector` (*address*) - address of the fee collector contract +#### updateReferrerShare + + ```solidity + function updateReferrerShare(address referrer, uint256 shareRatioD18) external + ``` + + Update the referral share percentage for a referrer + +**Parameters** +* `referrer` (*address*) - The address of the referrer +* `shareRatioD18` (*uint256*) - The new share percentage for the referrer + +#### getReferrerShare + + ```solidity + function getReferrerShare(address referrer) external returns (uint256 shareRatioD18) + ``` + + get the referral share percentage for the specified referrer + +**Parameters** +* `referrer` (*address*) - The address of the referrer + +**Returns** +* `shareRatioD18` (*uint256*) - The configured share percentage for the referrer + +#### MaxCollateralAmountSet + + ```solidity + event MaxCollateralAmountSet(uint128 synthMarketId, uint256 collateralAmount) + ``` + + Gets fired when max collateral amount for synth for all the markets is set by owner. + +**Parameters** +* `synthMarketId` (*uint128*) - Synth market id, 0 for snxUSD. +* `collateralAmount` (*uint256*) - max amount that was set for the synth + +#### SynthDeductionPrioritySet + + ```solidity + event SynthDeductionPrioritySet(uint128[] newSynthDeductionPriority) + ``` + + Gets fired when the synth deduction priority is updated by owner. + +**Parameters** +* `newSynthDeductionPriority` (*uint128[]*) - new synth id priority order for deductions. + +#### LiquidationRewardGuardsSet + + ```solidity + event LiquidationRewardGuardsSet(uint256 minLiquidationRewardUsd, uint256 maxLiquidationRewardUsd) + ``` + + Gets fired when liquidation reward guard is set or updated. + +**Parameters** +* `minLiquidationRewardUsd` (*uint256*) - Minimum liquidation reward expressed as USD value. +* `maxLiquidationRewardUsd` (*uint256*) - Maximum liquidation reward expressed as USD value. + +#### FeeCollectorSet + + ```solidity + event FeeCollectorSet(address feeCollector) + ``` + + emitted when custom fee collector is set + +**Parameters** +* `feeCollector` (*address*) - the address of the fee collector to set. + +#### ReferrerShareUpdated + + ```solidity + event ReferrerShareUpdated(address referrer, uint256 shareRatioD18) + ``` + + Emitted when the share percentage for a referrer address has been updated. + +**Parameters** +* `referrer` (*address*) - The address of the referrer +* `shareRatioD18` (*uint256*) - The new share ratio for the referrer + +### Liquidation Module + +#### liquidate + + ```solidity + function liquidate(uint128 accountId) external + ``` + +#### liquidateFlagged + + ```solidity + function liquidateFlagged() external + ``` + +#### PositionLiquidated + + ```solidity + event PositionLiquidated(uint128 accountId, uint128 marketId, uint256 amountLiquidated, int128 currentPositionSize) + ``` + +#### AccountLiquidated + + ```solidity + event AccountLiquidated(uint128 accountId, uint256 reward, bool fullLiquidation) + ``` + +### Market Configuration Module + +#### addSettlementStrategy + + ```solidity + function addSettlementStrategy(uint128 marketId, struct SettlementStrategy.Data strategy) external returns (uint256 strategyId) + ``` + + Add a new settlement strategy with this function. + +**Parameters** +* `marketId` (*uint128*) - id of the market to add the settlement strategy. +* `strategy` (*struct SettlementStrategy.Data*) - strategy details (see SettlementStrategy.Data struct). + +**Returns** +* `strategyId` (*uint256*) - id of the new settlement strategy. +#### setOrderFees + + ```solidity + function setOrderFees(uint128 marketId, uint256 makerFeeRatio, uint256 takerFeeRatio) external + ``` + + Set order fees for a market with this function. + +**Parameters** +* `marketId` (*uint128*) - id of the market to set order fees. +* `makerFeeRatio` (*uint256*) - the maker fee ratio. +* `takerFeeRatio` (*uint256*) - the taker fee ratio. + +#### updatePriceData + + ```solidity + function updatePriceData(uint128 perpsMarketId, bytes32 feedId) external + ``` + + Set node id for perps market + +**Parameters** +* `perpsMarketId` (*uint128*) - id of the market to set price feed. +* `feedId` (*bytes32*) - the node feed id + +#### setFundingParameters + + ```solidity + function setFundingParameters(uint128 marketId, uint256 skewScale, uint256 maxFundingVelocity) external + ``` + + Set funding parameters for a market with this function. + +**Parameters** +* `marketId` (*uint128*) - id of the market to set funding parameters. +* `skewScale` (*uint256*) - the skew scale. +* `maxFundingVelocity` (*uint256*) - the max funding velocity. + +#### setLiquidationParameters + + ```solidity + function setLiquidationParameters(uint128 marketId, uint256 initialMarginRatioD18, uint256 minimumInitialMarginRatioD18, uint256 maintenanceMarginScalarD18, uint256 liquidationRewardRatioD18, uint256 maxLiquidationLimitAccumulationMultiplier, uint256 maxSecondsInLiquidationWindow, uint256 minimumPositionMargin) external + ``` + + Set liquidation parameters for a market with this function. + +**Parameters** +* `marketId` (*uint128*) - id of the market to set liquidation parameters. +* `initialMarginRatioD18` (*uint256*) - the initial margin ratio (as decimal with 18 digits precision). +* `minimumInitialMarginRatioD18` (*uint256*) - the minimum initial margin ratio (as decimal with 18 digits precision). +* `maintenanceMarginScalarD18` (*uint256*) - the maintenance margin scalar relative to the initial margin ratio (as decimal with 18 digits precision). +* `liquidationRewardRatioD18` (*uint256*) - the liquidation reward ratio (as decimal with 18 digits precision). +* `maxLiquidationLimitAccumulationMultiplier` (*uint256*) - the max liquidation limit accumulation multiplier. +* `maxSecondsInLiquidationWindow` (*uint256*) - the max seconds in liquidation window (used together with the acc multiplier to get max liquidation per window). +* `minimumPositionMargin` (*uint256*) - the minimum position margin. + +#### setMaxMarketSize + + ```solidity + function setMaxMarketSize(uint128 marketId, uint256 maxMarketSize) external + ``` + + Set the max size of an specific market with this function. + + This controls the maximum open interest a market can have on either side (Long | Short). So the total Open Interest (with zero skew) for a market can be up to max market size * 2. + +**Parameters** +* `marketId` (*uint128*) - id of the market to set the max market value. +* `maxMarketSize` (*uint256*) - the max market size in market asset units. + +#### setLockedOiRatio + + ```solidity + function setLockedOiRatio(uint128 marketId, uint256 lockedOiRatioD18) external + ``` + + Set the locked OI Ratio for a market with this function. + +**Parameters** +* `marketId` (*uint128*) - id of the market to set locked OI ratio. +* `lockedOiRatioD18` (*uint256*) - the locked OI ratio skew scale (as decimal with 18 digits precision). + +#### setSettlementStrategyEnabled + + ```solidity + function setSettlementStrategyEnabled(uint128 marketId, uint256 strategyId, bool enabled) external + ``` + + Enable or disable a settlement strategy for a market with this function. + +**Parameters** +* `marketId` (*uint128*) - id of the market. +* `strategyId` (*uint256*) - the specific strategy. +* `enabled` (*bool*) - whether the strategy is enabled or disabled. + +#### getSettlementStrategy + + ```solidity + function getSettlementStrategy(uint128 marketId, uint256 strategyId) external view returns (struct SettlementStrategy.Data settlementStrategy) + ``` + + Gets the settlement strategy details. + +**Parameters** +* `marketId` (*uint128*) - id of the market. +* `strategyId` (*uint256*) - id of the settlement strategy. + +**Returns** +* `settlementStrategy` (*struct SettlementStrategy.Data*) - strategy details (see SettlementStrategy.Data struct). +#### getLiquidationParameters + + ```solidity + function getLiquidationParameters(uint128 marketId) external view returns (uint256 initialMarginRatioD18, uint256 minimumInitialMarginRatioD18, uint256 maintenanceMarginScalarD18, uint256 liquidationRewardRatioD18, uint256 maxLiquidationLimitAccumulationMultiplier, uint256 maxSecondsInLiquidationWindow, uint256 minimumPositionMargin) + ``` + + Gets liquidation parameters details of a market. + +**Parameters** +* `marketId` (*uint128*) - id of the market. + +**Returns** +* `initialMarginRatioD18` (*uint256*) - the initial margin ratio (as decimal with 18 digits precision). +* `minimumInitialMarginRatioD18` (*uint256*) - the minimum initial margin ratio (as decimal with 18 digits precision). +* `maintenanceMarginScalarD18` (*uint256*) - the maintenance margin scalar relative to the initial margin ratio (as decimal with 18 digits precision). +* `liquidationRewardRatioD18` (*uint256*) - the liquidation reward ratio (as decimal with 18 digits precision). +* `maxLiquidationLimitAccumulationMultiplier` (*uint256*) - the max liquidation limit accumulation multiplier. +* `maxSecondsInLiquidationWindow` (*uint256*) - the max seconds in liquidation window (used together with the acc multiplier to get max liquidation per window). +* `minimumPositionMargin` (*uint256*) - the minimum position margin. +#### getFundingParameters + + ```solidity + function getFundingParameters(uint128 marketId) external view returns (uint256 skewScale, uint256 maxFundingVelocity) + ``` + + Gets funding parameters of a market. + +**Parameters** +* `marketId` (*uint128*) - id of the market. + +**Returns** +* `skewScale` (*uint256*) - the skew scale. +* `maxFundingVelocity` (*uint256*) - the max funding velocity. +#### getMaxMarketSize + + ```solidity + function getMaxMarketSize(uint128 marketId) external view returns (uint256 maxMarketSize) + ``` + + Gets the max size of an specific market. + +**Parameters** +* `marketId` (*uint128*) - id of the market. + +**Returns** +* `maxMarketSize` (*uint256*) - the max market size in market asset units. +#### getOrderFees + + ```solidity + function getOrderFees(uint128 marketId) external view returns (uint256 makerFeeRatio, uint256 takerFeeRatio) + ``` + + Gets the order fees of a market. + +**Parameters** +* `marketId` (*uint128*) - id of the market. + +**Returns** +* `makerFeeRatio` (*uint256*) - the maker fee ratio. +* `takerFeeRatio` (*uint256*) - the taker fee ratio. +#### getLockedOiRatio + + ```solidity + function getLockedOiRatio(uint128 marketId) external view returns (uint256 lockedOiRatioD18) + ``` + + Gets the locked OI ratio of a market. + +**Parameters** +* `marketId` (*uint128*) - id of the market. + +**Returns** +* `lockedOiRatioD18` (*uint256*) - the locked OI ratio skew scale (as decimal with 18 digits precision). + +#### SettlementStrategyAdded + + ```solidity + event SettlementStrategyAdded(uint128 marketId, struct SettlementStrategy.Data strategy, uint256 strategyId) + ``` + + Gets fired when new settlement strategy is added. + +**Parameters** +* `marketId` (*uint128*) - adds settlement strategy to this specific market. +* `strategy` (*struct SettlementStrategy.Data*) - the strategy configuration. +* `strategyId` (*uint256*) - the newly created settlement strategy id. + +#### MarketPriceDataUpdated + + ```solidity + event MarketPriceDataUpdated(uint128 marketId, bytes32 feedId) + ``` + + Gets fired when feed id for perps market is updated. + +**Parameters** +* `marketId` (*uint128*) - id of perps market +* `feedId` (*bytes32*) - oracle node id + +#### OrderFeesSet + + ```solidity + event OrderFeesSet(uint128 marketId, uint256 makerFeeRatio, uint256 takerFeeRatio) + ``` + + Gets fired when order fees are updated. + +**Parameters** +* `marketId` (*uint128*) - udpates fees to this specific market. +* `makerFeeRatio` (*uint256*) - the maker fee ratio. +* `takerFeeRatio` (*uint256*) - the taker fee ratio. + +#### FundingParametersSet + + ```solidity + event FundingParametersSet(uint128 marketId, uint256 skewScale, uint256 maxFundingVelocity) + ``` + + Gets fired when funding parameters are updated. + +**Parameters** +* `marketId` (*uint128*) - udpates funding parameters to this specific market. +* `skewScale` (*uint256*) - the skew scale. +* `maxFundingVelocity` (*uint256*) - the max funding velocity. + +#### LiquidationParametersSet + + ```solidity + event LiquidationParametersSet(uint128 marketId, uint256 initialMarginRatioD18, uint256 maintenanceMarginRatioD18, uint256 minimumInitialMarginRatioD18, uint256 liquidationRewardRatioD18, uint256 maxLiquidationLimitAccumulationMultiplier, uint256 maxSecondsInLiquidationWindow, uint256 minimumPositionMargin) + ``` + + Gets fired when liquidation parameters are updated. + +**Parameters** +* `marketId` (*uint128*) - udpates funding parameters to this specific market. +* `initialMarginRatioD18` (*uint256*) - the initial margin ratio (as decimal with 18 digits precision). +* `maintenanceMarginRatioD18` (*uint256*) - the maintenance margin ratio (as decimal with 18 digits precision). +* `minimumInitialMarginRatioD18` (*uint256*) - +* `liquidationRewardRatioD18` (*uint256*) - the liquidation reward ratio (as decimal with 18 digits precision). +* `maxLiquidationLimitAccumulationMultiplier` (*uint256*) - the max liquidation limit accumulation multiplier. +* `maxSecondsInLiquidationWindow` (*uint256*) - the max seconds in liquidation window (used together with the acc multiplier to get max liquidation per window). +* `minimumPositionMargin` (*uint256*) - the minimum position margin. + +#### MaxMarketSizeSet + + ```solidity + event MaxMarketSizeSet(uint128 marketId, uint256 maxMarketSize) + ``` + + Gets fired when max market value is updated. + +**Parameters** +* `marketId` (*uint128*) - udpates funding parameters to this specific market. +* `maxMarketSize` (*uint256*) - the max market value. + +#### LockedOiRatioSet + + ```solidity + event LockedOiRatioSet(uint128 marketId, uint256 lockedOiRatioD18) + ``` + + Gets fired when locked oi ratio is updated. + +**Parameters** +* `marketId` (*uint128*) - udpates funding parameters to this specific market. +* `lockedOiRatioD18` (*uint256*) - the locked OI ratio skew scale (as decimal with 18 digits precision). + +#### SettlementStrategyEnabled + + ```solidity + event SettlementStrategyEnabled(uint128 marketId, uint256 strategyId, bool enabled) + ``` + + Gets fired when a settlement strategy is enabled or disabled. + +**Parameters** +* `marketId` (*uint128*) - udpates funding parameters to this specific market. +* `strategyId` (*uint256*) - the specific strategy. +* `enabled` (*bool*) - whether the strategy is enabled or disabled. + +### IMarketEvents + +#### MarketUpdated + + ```solidity + event MarketUpdated(uint128 marketId, uint256 price, int256 skew, uint256 size, int256 sizeDelta, int256 currentFundingRate, int256 currentFundingVelocity) + ``` + + Gets fired when the size of a market is updated by new orders or liquidations. + +**Parameters** +* `marketId` (*uint128*) - Id of the market used for the trade. +* `price` (*uint256*) - Price at the time of this event. +* `skew` (*int256*) - Market skew at the time of the trade. Positive values mean more longs. +* `size` (*uint256*) - Size of the entire market after settlement. +* `sizeDelta` (*int256*) - Change in market size during this update. +* `currentFundingRate` (*int256*) - The current funding rate of this market (0.001 = 0.1% per day) +* `currentFundingVelocity` (*int256*) - The current rate of change of the funding rate (0.001 = +0.1% per day) + +### Perps Account Module + +#### modifyCollateral + + ```solidity + function modifyCollateral(uint128 accountId, uint128 synthMarketId, int256 amountDelta) external + ``` + + Modify the collateral delegated to the account. + +**Parameters** +* `accountId` (*uint128*) - Id of the account. +* `synthMarketId` (*uint128*) - Id of the synth market used as collateral. Synth market id, 0 for snxUSD. +* `amountDelta` (*int256*) - requested change in amount of collateral delegated to the account. + +#### getCollateralAmount + + ```solidity + function getCollateralAmount(uint128 accountId, uint128 synthMarketId) external view returns (uint256) + ``` + + Gets the account's collateral value for a specific collateral. + +**Parameters** +* `accountId` (*uint128*) - Id of the account. +* `synthMarketId` (*uint128*) - Id of the synth market used as collateral. Synth market id, 0 for snxUSD. + +**Returns** +* `[0]` (*uint256*) - collateralValue collateral value of the account. +#### totalCollateralValue + + ```solidity + function totalCollateralValue(uint128 accountId) external view returns (uint256) + ``` + + Gets the account's total collateral value. + +**Parameters** +* `accountId` (*uint128*) - Id of the account. + +**Returns** +* `[0]` (*uint256*) - collateralValue total collateral value of the account. USD denominated. +#### totalAccountOpenInterest + + ```solidity + function totalAccountOpenInterest(uint128 accountId) external view returns (uint256) + ``` + + Gets the account's total open interest value. + +**Parameters** +* `accountId` (*uint128*) - Id of the account. + +**Returns** +* `[0]` (*uint256*) - openInterestValue total open interest value of the account. +#### getOpenPosition + + ```solidity + function getOpenPosition(uint128 accountId, uint128 marketId) external view returns (int256 totalPnl, int256 accruedFunding, int128 positionSize) + ``` + + Gets the details of an open position. + +**Parameters** +* `accountId` (*uint128*) - Id of the account. +* `marketId` (*uint128*) - Id of the position market. + +**Returns** +* `totalPnl` (*int256*) - pnl of the entire position including funding. +* `accruedFunding` (*int256*) - accrued funding of the position. +* `positionSize` (*int128*) - size of the position. +#### getAvailableMargin + + ```solidity + function getAvailableMargin(uint128 accountId) external view returns (int256 availableMargin) + ``` + + Gets the available margin of an account. It can be negative due to pnl. + +**Parameters** +* `accountId` (*uint128*) - Id of the account. + +**Returns** +* `availableMargin` (*int256*) - available margin of the position. +#### getWithdrawableMargin + + ```solidity + function getWithdrawableMargin(uint128 accountId) external view returns (int256 withdrawableMargin) + ``` + + Gets the exact withdrawable amount a trader has available from this account while holding the account's current positions. + +**Parameters** +* `accountId` (*uint128*) - Id of the account. + +**Returns** +* `withdrawableMargin` (*int256*) - available margin to withdraw. +#### getRequiredMargins + + ```solidity + function getRequiredMargins(uint128 accountId) external view returns (uint256 requiredInitialMargin, uint256 requiredMaintenanceMargin) + ``` + + Gets the initial/maintenance margins across all positions that an account has open. + +**Parameters** +* `accountId` (*uint128*) - Id of the account. + +**Returns** +* `requiredInitialMargin` (*uint256*) - initial margin req (used when withdrawing collateral). +* `requiredMaintenanceMargin` (*uint256*) - maintenance margin req (used to determine liquidation threshold). + +#### CollateralModified + + ```solidity + event CollateralModified(uint128 accountId, uint128 synthMarketId, int256 amountDelta, address sender) + ``` + + Gets fired when an account colateral is modified. + +**Parameters** +* `accountId` (*uint128*) - Id of the account. +* `synthMarketId` (*uint128*) - Id of the synth market used as collateral. Synth market id, 0 for snxUSD. +* `amountDelta` (*int256*) - requested change in amount of collateral delegated to the account. +* `sender` (*address*) - address of the sender of the size modification. Authorized by account owner. + +### Perps Market Factory Module + +#### initializeFactory + + ```solidity + function initializeFactory() external returns (uint128) + ``` + +#### setSynthetix + + ```solidity + function setSynthetix(contract ISynthetixSystem synthetix) external + ``` + +#### setSpotMarket + + ```solidity + function setSpotMarket(contract ISpotMarketSystem spotMarket) external + ``` + +#### createMarket + + ```solidity + function createMarket(uint128 requestedMarketId, string marketName, string marketSymbol) external returns (uint128) + ``` + +#### name + + ```solidity + function name(uint128 marketId) external view returns (string) + ``` + + returns a human-readable name for a given market + +#### reportedDebt + + ```solidity + function reportedDebt(uint128 marketId) external view returns (uint256) + ``` + + returns amount of USD that the market would try to mint if everything was withdrawn + +#### minimumCredit + + ```solidity + function minimumCredit(uint128 marketId) external view returns (uint256) + ``` + + prevents reduction of available credit capacity by specifying this amount, for which withdrawals will be disallowed + +#### supportsInterface + + ```solidity + function supportsInterface(bytes4 interfaceID) external view returns (bool) + ``` + + Determines if the contract in question supports the specified interface. + +**Parameters** +* `interfaceID` (*bytes4*) - XOR of all selectors in the contract. + +**Returns** +* `[0]` (*bool*) - True if the contract supports the specified interface. + +#### FactoryInitialized + + ```solidity + event FactoryInitialized(uint128 globalPerpsMarketId) + ``` + +#### MarketCreated + + ```solidity + event MarketCreated(uint128 perpsMarketId, string marketName, string marketSymbol) + ``` + +### Perps Market Module + +#### metadata + + ```solidity + function metadata(uint128 marketId) external view returns (string name, string symbol) + ``` + +#### skew + + ```solidity + function skew(uint128 marketId) external view returns (int256) + ``` + +#### size + + ```solidity + function size(uint128 marketId) external view returns (uint256) + ``` + +#### maxOpenInterest + + ```solidity + function maxOpenInterest(uint128 marketId) external view returns (uint256) + ``` + +#### currentFundingRate + + ```solidity + function currentFundingRate(uint128 marketId) external view returns (int256) + ``` + +#### currentFundingVelocity + + ```solidity + function currentFundingVelocity(uint128 marketId) external view returns (int256) + ``` + +#### indexPrice + + ```solidity + function indexPrice(uint128 marketId) external view returns (uint256) + ``` + +#### fillPrice + + ```solidity + function fillPrice(uint128 marketId, int128 orderSize, uint256 price) external returns (uint256) + ``` + +#### getMarketSummary + + ```solidity + function getMarketSummary(uint128 marketId) external view returns (struct IPerpsMarketModule.MarketSummary summary) + ``` + + Given a marketId return a market's summary details in one call. + +## Governance + +- [Back to TOC](#smart-contracts) + +### Council Token Module + +#### isInitialized + + ```solidity + function isInitialized() external returns (bool) + ``` + + Returns whether the token has been initialized. + +**Returns** +* `[0]` (*bool*) - A boolean with the result of the query. +#### initialize + + ```solidity + function initialize(string tokenName, string tokenSymbol, string uri) external + ``` + + Initializes the token with name, symbol, and uri. + +#### mint + + ```solidity + function mint(address to, uint256 tokenId) external + ``` + + Allows the owner to mint tokens. + +**Parameters** +* `to` (*address*) - The address to receive the newly minted tokens. +* `tokenId` (*uint256*) - The ID of the newly minted token + +#### safeMint + + ```solidity + function safeMint(address to, uint256 tokenId, bytes data) external + ``` + + Allows the owner to mint tokens. Verifies that the receiver can receive the token + +**Parameters** +* `to` (*address*) - The address to receive the newly minted token. +* `tokenId` (*uint256*) - The ID of the newly minted token +* `data` (*bytes*) - any data which should be sent to the receiver + +#### burn + + ```solidity + function burn(uint256 tokenId) external + ``` + + Allows the owner to burn tokens. + +**Parameters** +* `tokenId` (*uint256*) - The token to burn + +#### setAllowance + + ```solidity + function setAllowance(uint256 tokenId, address spender) external + ``` + + Allows an address that holds tokens to provide allowance to another. + +**Parameters** +* `tokenId` (*uint256*) - The token which should be allowed to spender +* `spender` (*address*) - The address that is given allowance. + +#### setBaseTokenURI + + ```solidity + function setBaseTokenURI(string uri) external + ``` + + Allows the owner to update the base token URI. + +**Parameters** +* `uri` (*string*) - The new base token uri + +#### totalSupply + + ```solidity + function totalSupply() external view returns (uint256) + ``` + + Returns the total amount of tokens stored by the contract. + +#### tokenOfOwnerByIndex + + ```solidity + function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256) + ``` + + Returns a token ID owned by `owner` at a given `index` of its token list. +Use along with {balanceOf} to enumerate all of ``owner``'s tokens. + +Requirements: +- `owner` must be a valid address +- `index` must be less than the balance of the tokens for the owner + +#### tokenByIndex + + ```solidity + function tokenByIndex(uint256 index) external view returns (uint256) + ``` + + Returns a token ID at a given `index` of all the tokens stored by the contract. +Use along with {totalSupply} to enumerate all tokens. + +Requirements: +- `index` must be less than the total supply of the tokens + +#### balanceOf + + ```solidity + function balanceOf(address holder) external view returns (uint256 balance) + ``` + + Returns the number of tokens in ``owner``'s account. + +Requirements: + +- `holder` must be a valid address + +#### ownerOf + + ```solidity + function ownerOf(uint256 tokenId) external view returns (address owner) + ``` + + Returns the owner of the `tokenId` token. + +Requirements: + +- `tokenId` must exist. + +#### safeTransferFrom + + ```solidity + function safeTransferFrom(address from, address to, uint256 tokenId, bytes data) external + ``` + + Safely transfers `tokenId` token from `from` to `to`. + +Requirements: + +- `from` cannot be the zero address. +- `to` cannot be the zero address. +- `tokenId` token must exist and be owned by `from`. +- If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. +- If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. + +Emits a {Transfer} event. + +#### safeTransferFrom + + ```solidity + function safeTransferFrom(address from, address to, uint256 tokenId) external + ``` + + Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients +are aware of the ERC721 protocol to prevent tokens from being forever locked. + +Requirements: + +- `from` cannot be the zero address. +- `to` cannot be the zero address. +- `tokenId` token must exist and be owned by `from`. +- If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}. +- If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. + +Emits a {Transfer} event. + +#### transferFrom + + ```solidity + function transferFrom(address from, address to, uint256 tokenId) external + ``` + + Transfers `tokenId` token from `from` to `to`. + +WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible. + +Requirements: + +- `from` cannot be the zero address. +- `to` cannot be the zero address. +- `tokenId` token must be owned by `from`. +- If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. + +Emits a {Transfer} event. + +#### approve + + ```solidity + function approve(address to, uint256 tokenId) external + ``` + + Gives permission to `to` to transfer `tokenId` token to another account. +The approval is cleared when the token is transferred. + +Only a single account can be approved at a time, so approving the zero address clears previous approvals. + +Requirements: + +- The caller must own the token or be an approved operator. +- `tokenId` must exist. + +Emits an {Approval} event. + +#### setApprovalForAll + + ```solidity + function setApprovalForAll(address operator, bool approved) external + ``` + + Approve or remove `operator` as an operator for the caller. +Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. + +Requirements: + +- The `operator` cannot be the caller. + +Emits an {ApprovalForAll} event. + +#### getApproved + + ```solidity + function getApproved(uint256 tokenId) external view returns (address operator) + ``` + + Returns the account approved for `tokenId` token. + +Requirements: + +- `tokenId` must exist. + +#### isApprovedForAll + + ```solidity + function isApprovedForAll(address owner, address operator) external view returns (bool) + ``` + + Returns if the `operator` is allowed to manage all of the assets of `owner`. + +See {setApprovalForAll} + +#### Transfer + + ```solidity + event Transfer(address from, address to, uint256 tokenId) + ``` + + Emitted when `tokenId` token is transferred from `from` to `to`. + +#### Approval + + ```solidity + event Approval(address owner, address approved, uint256 tokenId) + ``` + + Emitted when `owner` enables `approved` to manage the `tokenId` token. + +#### ApprovalForAll + + ```solidity + event ApprovalForAll(address owner, address operator, bool approved) + ``` + + Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets. + +### IDebtShare + +#### balanceOfOnPeriod + + ```solidity + function balanceOfOnPeriod(address account, uint256 periodId) external view returns (uint256) + ``` + +### Election Inspector Module + +#### getEpochStartDateForIndex + + ```solidity + function getEpochStartDateForIndex(uint256 epochIndex) external view returns (uint64) + ``` + + Returns the date in which the given epoch started + +#### getEpochEndDateForIndex + + ```solidity + function getEpochEndDateForIndex(uint256 epochIndex) external view returns (uint64) + ``` + + Returns the date in which the given epoch ended + +#### getNominationPeriodStartDateForIndex + + ```solidity + function getNominationPeriodStartDateForIndex(uint256 epochIndex) external view returns (uint64) + ``` + + Returns the date in which the Nomination period in the given epoch started + +#### getVotingPeriodStartDateForIndex + + ```solidity + function getVotingPeriodStartDateForIndex(uint256 epochIndex) external view returns (uint64) + ``` + + Returns the date in which the Voting period in the given epoch started + +#### wasNominated + + ```solidity + function wasNominated(address candidate, uint256 epochIndex) external view returns (bool) + ``` + + Shows if a candidate was nominated in the given epoch + +#### getNomineesAtEpoch + + ```solidity + function getNomineesAtEpoch(uint256 epochIndex) external view returns (address[]) + ``` + + Returns a list of all nominated candidates in the given epoch + +#### getBallotVotedAtEpoch + + ```solidity + function getBallotVotedAtEpoch(address user, uint256 epochIndex) external view returns (bytes32) + ``` + + Returns the ballot id that user voted on in the given election + +#### hasVotedInEpoch + + ```solidity + function hasVotedInEpoch(address user, uint256 epochIndex) external view returns (bool) + ``` + + Returns if user has voted in the given election + +#### getBallotVotesInEpoch + + ```solidity + function getBallotVotesInEpoch(bytes32 ballotId, uint256 epochIndex) external view returns (uint256) + ``` + + Returns the number of votes given to a particular ballot in a given epoch + +#### getBallotCandidatesInEpoch + + ```solidity + function getBallotCandidatesInEpoch(bytes32 ballotId, uint256 epochIndex) external view returns (address[]) + ``` + + Returns the list of candidates that a particular ballot has in a given epoch + +#### getCandidateVotesInEpoch + + ```solidity + function getCandidateVotesInEpoch(address candidate, uint256 epochIndex) external view returns (uint256) + ``` + + Returns the number of votes a candidate received in a given epoch + +#### getElectionWinnersInEpoch + + ```solidity + function getElectionWinnersInEpoch(uint256 epochIndex) external view returns (address[]) + ``` + + Returns the winners of the given election + +### Election Module + +#### initOrUpgradeElectionModule + + ```solidity + function initOrUpgradeElectionModule(address[] firstCouncil, uint8 minimumActiveMembers, uint64 nominationPeriodStartDate, uint64 votingPeriodStartDate, uint64 epochEndDate) external + ``` + + Initializes the module and immediately starts the first epoch + +#### isElectionModuleInitialized + + ```solidity + function isElectionModuleInitialized() external view returns (bool) + ``` + + Shows whether the module has been initialized + +#### tweakEpochSchedule + + ```solidity + function tweakEpochSchedule(uint64 newNominationPeriodStartDate, uint64 newVotingPeriodStartDate, uint64 newEpochEndDate) external + ``` + + Adjusts the current epoch schedule requiring that the current period remains Administration, and that changes are small (see setMaxDateAdjustmentTolerance) + +#### modifyEpochSchedule + + ```solidity + function modifyEpochSchedule(uint64 newNominationPeriodStartDate, uint64 newVotingPeriodStartDate, uint64 newEpochEndDate) external + ``` + + Adjusts the current epoch schedule requiring that the current period remains Administration + +#### setMinEpochDurations + + ```solidity + function setMinEpochDurations(uint64 newMinNominationPeriodDuration, uint64 newMinVotingPeriodDuration, uint64 newMinEpochDuration) external + ``` + + Determines minimum values for epoch schedule adjustments + +#### setMaxDateAdjustmentTolerance + + ```solidity + function setMaxDateAdjustmentTolerance(uint64 newMaxDateAdjustmentTolerance) external + ``` + + Determines adjustment size for tweakEpochSchedule + +#### setDefaultBallotEvaluationBatchSize + + ```solidity + function setDefaultBallotEvaluationBatchSize(uint256 newDefaultBallotEvaluationBatchSize) external + ``` + + Determines batch size when evaluate() is called with numBallots = 0 + +#### setNextEpochSeatCount + + ```solidity + function setNextEpochSeatCount(uint8 newSeatCount) external + ``` + + Determines the number of council members in the next epoch + +#### setMinimumActiveMembers + + ```solidity + function setMinimumActiveMembers(uint8 newMinimumActiveMembers) external + ``` + + Determines the minimum number of council members before triggering an emergency election + +#### dismissMembers + + ```solidity + function dismissMembers(address[] members) external + ``` + + Allows the owner to remove one or more council members, triggering an election if a threshold is met + +#### nominate + + ```solidity + function nominate() external + ``` + + Allows anyone to self-nominate during the Nomination period + +#### withdrawNomination + + ```solidity + function withdrawNomination() external + ``` + + Self-withdrawal of nominations during the Nomination period + +#### cast + + ```solidity + function cast(address[] candidates) external + ``` + + Allows anyone with vote power to vote on nominated candidates during the Voting period + +#### withdrawVote + + ```solidity + function withdrawVote() external + ``` + + Allows votes to be withdraw + +#### evaluate + + ```solidity + function evaluate(uint256 numBallots) external + ``` + + Processes ballots in batches during the Evaluation period (after epochEndDate) + +#### resolve + + ```solidity + function resolve() external + ``` + + Shuffles NFTs and resolves an election after it has been evaluated + +#### getMinEpochDurations + + ```solidity + function getMinEpochDurations() external view returns (uint64 minNominationPeriodDuration, uint64 minVotingPeriodDuration, uint64 minEpochDuration) + ``` + + Exposes minimum durations required when adjusting epoch schedules + +#### getMaxDateAdjustmenTolerance + + ```solidity + function getMaxDateAdjustmenTolerance() external view returns (uint64) + ``` + + Exposes maximum size of adjustments when calling tweakEpochSchedule + +#### getDefaultBallotEvaluationBatchSize + + ```solidity + function getDefaultBallotEvaluationBatchSize() external view returns (uint256) + ``` + + Shows the default batch size when calling evaluate() with numBallots = 0 + +#### getNextEpochSeatCount + + ```solidity + function getNextEpochSeatCount() external view returns (uint8) + ``` + + Shows the number of council members that the next epoch will have + +#### getMinimumActiveMembers + + ```solidity + function getMinimumActiveMembers() external view returns (uint8) + ``` + + Returns the minimum active members that the council needs to avoid an emergency election + +#### getEpochIndex + + ```solidity + function getEpochIndex() external view returns (uint256) + ``` + + Returns the index of the current epoch. The first epoch's index is 1 + +#### getEpochStartDate + + ```solidity + function getEpochStartDate() external view returns (uint64) + ``` + + Returns the date in which the current epoch started + +#### getEpochEndDate + + ```solidity + function getEpochEndDate() external view returns (uint64) + ``` + + Returns the date in which the current epoch will end + +#### getNominationPeriodStartDate + + ```solidity + function getNominationPeriodStartDate() external view returns (uint64) + ``` + + Returns the date in which the Nomination period in the current epoch will start + +#### getVotingPeriodStartDate + + ```solidity + function getVotingPeriodStartDate() external view returns (uint64) + ``` + + Returns the date in which the Voting period in the current epoch will start + +#### getCurrentPeriod + + ```solidity + function getCurrentPeriod() external view returns (uint256) + ``` + + Returns the current period type: Administration, Nomination, Voting, Evaluation + +#### isNominated + + ```solidity + function isNominated(address candidate) external view returns (bool) + ``` + + Shows if a candidate has been nominated in the current epoch + +#### getNominees + + ```solidity + function getNominees() external view returns (address[]) + ``` + + Returns a list of all nominated candidates in the current epoch + +#### calculateBallotId + + ```solidity + function calculateBallotId(address[] candidates) external pure returns (bytes32) + ``` + + Hashes a list of candidates (used for identifying and storing ballots) + +#### getBallotVoted + + ```solidity + function getBallotVoted(address user) external view returns (bytes32) + ``` + + Returns the ballot id that user voted on in the current election + +#### hasVoted + + ```solidity + function hasVoted(address user) external view returns (bool) + ``` + + Returns if user has voted in the current election + +#### getVotePower + + ```solidity + function getVotePower(address user) external view returns (uint256) + ``` + + Returns the vote power of user in the current election + +#### getBallotVotes + + ```solidity + function getBallotVotes(bytes32 ballotId) external view returns (uint256) + ``` + + Returns the number of votes given to a particular ballot + +#### getBallotCandidates + + ```solidity + function getBallotCandidates(bytes32 ballotId) external view returns (address[]) + ``` + + Returns the list of candidates that a particular ballot has + +#### isElectionEvaluated + + ```solidity + function isElectionEvaluated() external view returns (bool) + ``` + + Returns whether all ballots in the current election have been counted + +#### getCandidateVotes + + ```solidity + function getCandidateVotes(address candidate) external view returns (uint256) + ``` + + Returns the number of votes a candidate received. Requires the election to be partially or totally evaluated + +#### getElectionWinners + + ```solidity + function getElectionWinners() external view returns (address[]) + ``` + + Returns the winners of the current election. Requires the election to be partially or totally evaluated + +#### getCouncilToken + + ```solidity + function getCouncilToken() external view returns (address) + ``` + + Returns the address of the council NFT token + +#### getCouncilMembers + + ```solidity + function getCouncilMembers() external view returns (address[]) + ``` + + Returns the current NFT token holders + +### Synthetix Election Module + +#### initOrUpgradeElectionModule + + ```solidity + function initOrUpgradeElectionModule(address[] firstCouncil, uint8 minimumActiveMembers, uint64 nominationPeriodStartDate, uint64 votingPeriodStartDate, uint64 epochEndDate, address debtShareContract) external + ``` + + Initializes the module and immediately starts the first epoch + +#### setDebtShareContract + + ```solidity + function setDebtShareContract(address newDebtShareContractAddress) external + ``` + + Sets the Synthetix v2 DebtShare contract that determines vote power + +#### getDebtShareContract + + ```solidity + function getDebtShareContract() external view returns (address) + ``` + + Returns the Synthetix v2 DebtShare contract that determines vote power + +#### setDebtShareSnapshotId + + ```solidity + function setDebtShareSnapshotId(uint256 snapshotId) external + ``` + + Sets the Synthetix v2 DebtShare snapshot that determines vote power for this epoch + +#### getDebtShareSnapshotId + + ```solidity + function getDebtShareSnapshotId() external view returns (uint256) + ``` + + Returns the Synthetix v2 DebtShare snapshot id set for this epoch + +#### getDebtShare + + ```solidity + function getDebtShare(address user) external view returns (uint256) + ``` + + Returns the Synthetix v2 debt share for the provided address, at this epoch's snapshot + +#### setCrossChainDebtShareMerkleRoot + + ```solidity + function setCrossChainDebtShareMerkleRoot(bytes32 merkleRoot, uint256 blocknumber) external + ``` + + Allows the system owner to declare a merkle root for user debt shares on other chains for this epoch + +#### getCrossChainDebtShareMerkleRoot + + ```solidity + function getCrossChainDebtShareMerkleRoot() external view returns (bytes32) + ``` + + Returns the current epoch's merkle root for user debt shares on other chains + +#### getCrossChainDebtShareMerkleRootBlockNumber + + ```solidity + function getCrossChainDebtShareMerkleRootBlockNumber() external view returns (uint256) + ``` + + Returns the current epoch's merkle root block number + +#### declareCrossChainDebtShare + + ```solidity + function declareCrossChainDebtShare(address account, uint256 debtShare, bytes32[] merkleProof) external + ``` + + Allows users to declare their Synthetix v2 debt shares on other chains + +#### getDeclaredCrossChainDebtShare + + ```solidity + function getDeclaredCrossChainDebtShare(address account) external view returns (uint256) + ``` + + Returns the Synthetix v2 debt shares for the provided address, at this epoch's snapshot, in other chains + +#### declareAndCast + + ```solidity + function declareAndCast(uint256 debtShare, bytes32[] merkleProof, address[] candidates) external + ``` + + Declares cross chain debt shares and casts a vote + +#### initOrUpgradeElectionModule + + ```solidity + function initOrUpgradeElectionModule(address[] firstCouncil, uint8 minimumActiveMembers, uint64 nominationPeriodStartDate, uint64 votingPeriodStartDate, uint64 epochEndDate) external + ``` + + Initializes the module and immediately starts the first epoch + +#### isElectionModuleInitialized + + ```solidity + function isElectionModuleInitialized() external view returns (bool) + ``` + + Shows whether the module has been initialized + +#### tweakEpochSchedule + + ```solidity + function tweakEpochSchedule(uint64 newNominationPeriodStartDate, uint64 newVotingPeriodStartDate, uint64 newEpochEndDate) external + ``` + + Adjusts the current epoch schedule requiring that the current period remains Administration, and that changes are small (see setMaxDateAdjustmentTolerance) + +#### modifyEpochSchedule + + ```solidity + function modifyEpochSchedule(uint64 newNominationPeriodStartDate, uint64 newVotingPeriodStartDate, uint64 newEpochEndDate) external + ``` + + Adjusts the current epoch schedule requiring that the current period remains Administration + +#### setMinEpochDurations + + ```solidity + function setMinEpochDurations(uint64 newMinNominationPeriodDuration, uint64 newMinVotingPeriodDuration, uint64 newMinEpochDuration) external + ``` + + Determines minimum values for epoch schedule adjustments + +#### setMaxDateAdjustmentTolerance + + ```solidity + function setMaxDateAdjustmentTolerance(uint64 newMaxDateAdjustmentTolerance) external + ``` + + Determines adjustment size for tweakEpochSchedule + +#### setDefaultBallotEvaluationBatchSize + + ```solidity + function setDefaultBallotEvaluationBatchSize(uint256 newDefaultBallotEvaluationBatchSize) external + ``` + + Determines batch size when evaluate() is called with numBallots = 0 + +#### setNextEpochSeatCount + + ```solidity + function setNextEpochSeatCount(uint8 newSeatCount) external + ``` + + Determines the number of council members in the next epoch + +#### setMinimumActiveMembers + + ```solidity + function setMinimumActiveMembers(uint8 newMinimumActiveMembers) external + ``` + + Determines the minimum number of council members before triggering an emergency election + +#### dismissMembers + + ```solidity + function dismissMembers(address[] members) external + ``` + + Allows the owner to remove one or more council members, triggering an election if a threshold is met + +#### nominate + + ```solidity + function nominate() external + ``` + + Allows anyone to self-nominate during the Nomination period + +#### withdrawNomination + + ```solidity + function withdrawNomination() external + ``` + + Self-withdrawal of nominations during the Nomination period + +#### cast + + ```solidity + function cast(address[] candidates) external + ``` + + Allows anyone with vote power to vote on nominated candidates during the Voting period + +#### withdrawVote + + ```solidity + function withdrawVote() external + ``` + + Allows votes to be withdraw + +#### evaluate + + ```solidity + function evaluate(uint256 numBallots) external + ``` + + Processes ballots in batches during the Evaluation period (after epochEndDate) + +#### resolve + + ```solidity + function resolve() external + ``` + + Shuffles NFTs and resolves an election after it has been evaluated + +#### getMinEpochDurations + + ```solidity + function getMinEpochDurations() external view returns (uint64 minNominationPeriodDuration, uint64 minVotingPeriodDuration, uint64 minEpochDuration) + ``` + + Exposes minimum durations required when adjusting epoch schedules + +#### getMaxDateAdjustmenTolerance + + ```solidity + function getMaxDateAdjustmenTolerance() external view returns (uint64) + ``` + + Exposes maximum size of adjustments when calling tweakEpochSchedule + +#### getDefaultBallotEvaluationBatchSize + + ```solidity + function getDefaultBallotEvaluationBatchSize() external view returns (uint256) + ``` + + Shows the default batch size when calling evaluate() with numBallots = 0 + +#### getNextEpochSeatCount + + ```solidity + function getNextEpochSeatCount() external view returns (uint8) + ``` + + Shows the number of council members that the next epoch will have + +#### getMinimumActiveMembers + + ```solidity + function getMinimumActiveMembers() external view returns (uint8) + ``` + + Returns the minimum active members that the council needs to avoid an emergency election + +#### getEpochIndex + + ```solidity + function getEpochIndex() external view returns (uint256) + ``` + + Returns the index of the current epoch. The first epoch's index is 1 + +#### getEpochStartDate + + ```solidity + function getEpochStartDate() external view returns (uint64) + ``` + + Returns the date in which the current epoch started + +#### getEpochEndDate + + ```solidity + function getEpochEndDate() external view returns (uint64) + ``` + + Returns the date in which the current epoch will end + +#### getNominationPeriodStartDate + + ```solidity + function getNominationPeriodStartDate() external view returns (uint64) + ``` + + Returns the date in which the Nomination period in the current epoch will start + +#### getVotingPeriodStartDate + + ```solidity + function getVotingPeriodStartDate() external view returns (uint64) + ``` + + Returns the date in which the Voting period in the current epoch will start + +#### getCurrentPeriod + + ```solidity + function getCurrentPeriod() external view returns (uint256) + ``` + + Returns the current period type: Administration, Nomination, Voting, Evaluation + +#### isNominated + + ```solidity + function isNominated(address candidate) external view returns (bool) + ``` + + Shows if a candidate has been nominated in the current epoch + +#### getNominees + + ```solidity + function getNominees() external view returns (address[]) + ``` + + Returns a list of all nominated candidates in the current epoch + +#### calculateBallotId + + ```solidity + function calculateBallotId(address[] candidates) external pure returns (bytes32) + ``` + + Hashes a list of candidates (used for identifying and storing ballots) + +#### getBallotVoted + + ```solidity + function getBallotVoted(address user) external view returns (bytes32) + ``` + + Returns the ballot id that user voted on in the current election + +#### hasVoted + + ```solidity + function hasVoted(address user) external view returns (bool) + ``` + + Returns if user has voted in the current election + +#### getVotePower + + ```solidity + function getVotePower(address user) external view returns (uint256) + ``` + + Returns the vote power of user in the current election + +#### getBallotVotes + + ```solidity + function getBallotVotes(bytes32 ballotId) external view returns (uint256) + ``` + + Returns the number of votes given to a particular ballot + +#### getBallotCandidates + + ```solidity + function getBallotCandidates(bytes32 ballotId) external view returns (address[]) + ``` + + Returns the list of candidates that a particular ballot has + +#### isElectionEvaluated + + ```solidity + function isElectionEvaluated() external view returns (bool) + ``` + + Returns whether all ballots in the current election have been counted + +#### getCandidateVotes + + ```solidity + function getCandidateVotes(address candidate) external view returns (uint256) + ``` + + Returns the number of votes a candidate received. Requires the election to be partially or totally evaluated + +#### getElectionWinners + + ```solidity + function getElectionWinners() external view returns (address[]) + ``` + + Returns the winners of the current election. Requires the election to be partially or totally evaluated + +#### getCouncilToken + + ```solidity + function getCouncilToken() external view returns (address) + ``` + + Returns the address of the council NFT token + +#### getCouncilMembers + + ```solidity + function getCouncilMembers() external view returns (address[]) + ``` + + Returns the current NFT token holders + +## Oracle Manager + +- [Back to TOC](#smart-contracts) + +### Node Module + +#### registerNode + + ```solidity + function registerNode(enum NodeDefinition.NodeType nodeType, bytes parameters, bytes32[] parents) external returns (bytes32 nodeId) + ``` + + Registers a node + +**Parameters** +* `nodeType` (*enum NodeDefinition.NodeType*) - The nodeType assigned to this node. +* `parameters` (*bytes*) - The parameters assigned to this node. +* `parents` (*bytes32[]*) - The parents assigned to this node. + +**Returns** +* `nodeId` (*bytes32*) - The id of the registered node. +#### getNodeId + + ```solidity + function getNodeId(enum NodeDefinition.NodeType nodeType, bytes parameters, bytes32[] parents) external returns (bytes32 nodeId) + ``` + + Returns the ID of a node, whether or not it has been registered. + +**Parameters** +* `nodeType` (*enum NodeDefinition.NodeType*) - The nodeType assigned to this node. +* `parameters` (*bytes*) - The parameters assigned to this node. +* `parents` (*bytes32[]*) - The parents assigned to this node. + +**Returns** +* `nodeId` (*bytes32*) - The id of the node. +#### getNode + + ```solidity + function getNode(bytes32 nodeId) external pure returns (struct NodeDefinition.Data node) + ``` + + Returns a node's definition (type, parameters, and parents) + +**Parameters** +* `nodeId` (*bytes32*) - The node ID + +**Returns** +* `node` (*struct NodeDefinition.Data*) - The node's definition data +#### process + + ```solidity + function process(bytes32 nodeId) external view returns (struct NodeOutput.Data node) + ``` + + Returns a node current output data + +**Parameters** +* `nodeId` (*bytes32*) - The node ID + +**Returns** +* `node` (*struct NodeOutput.Data*) - The node's output data + +#### NodeRegistered + + ```solidity + event NodeRegistered(bytes32 nodeId, enum NodeDefinition.NodeType nodeType, bytes parameters, bytes32[] parents) + ``` + + Emitted when `registerNode` is called. + +**Parameters** +* `nodeId` (*bytes32*) - The id of the registered node. +* `nodeType` (*enum NodeDefinition.NodeType*) - The nodeType assigned to this node. +* `parameters` (*bytes*) - The parameters assigned to this node. +* `parents` (*bytes32[]*) - The parents assigned to this node. + +### ChainlinkNode + +#### process + + ```solidity + function process(bytes parameters) internal view returns (struct NodeOutput.Data nodeOutput) + ``` + +#### getTwapPrice + + ```solidity + function getTwapPrice(contract IAggregatorV3Interface chainlink, uint80 latestRoundId, int256 latestPrice, uint256 twapTimeInterval) internal view returns (int256 price) + ``` + +#### isValid + + ```solidity + function isValid(struct NodeDefinition.Data nodeDefinition) internal view returns (bool valid) + ``` + +### ConstantNode + +#### process + + ```solidity + function process(bytes parameters) internal view returns (struct NodeOutput.Data nodeOutput) + ``` + +#### isValid + + ```solidity + function isValid(struct NodeDefinition.Data nodeDefinition) internal pure returns (bool valid) + ``` + +### ExternalNode + +#### process + + ```solidity + function process(struct NodeOutput.Data[] prices, bytes parameters) internal view returns (struct NodeOutput.Data nodeOutput) + ``` + +#### isValid + + ```solidity + function isValid(struct NodeDefinition.Data nodeDefinition) internal returns (bool valid) + ``` + +### PriceDeviationCircuitBreakerNode + +#### process + + ```solidity + function process(struct NodeOutput.Data[] parentNodeOutputs, bytes parameters) internal pure returns (struct NodeOutput.Data nodeOutput) + ``` + +#### abs + + ```solidity + function abs(int256 x) private pure returns (int256 result) + ``` + +#### isValid + + ```solidity + function isValid(struct NodeDefinition.Data nodeDefinition) internal pure returns (bool valid) + ``` + +### PythNode + +#### process + + ```solidity + function process(bytes parameters) internal view returns (struct NodeOutput.Data nodeOutput) + ``` + +#### isValid + + ```solidity + function isValid(struct NodeDefinition.Data nodeDefinition) internal view returns (bool valid) + ``` + +### ReducerNode + +#### process + + ```solidity + function process(struct NodeOutput.Data[] parentNodeOutputs, bytes parameters) internal pure returns (struct NodeOutput.Data nodeOutput) + ``` + +#### median + + ```solidity + function median(struct NodeOutput.Data[] parentNodeOutputs) internal pure returns (struct NodeOutput.Data medianPrice) + ``` + +#### mean + + ```solidity + function mean(struct NodeOutput.Data[] parentNodeOutputs) internal pure returns (struct NodeOutput.Data meanPrice) + ``` + +#### recent + + ```solidity + function recent(struct NodeOutput.Data[] parentNodeOutputs) internal pure returns (struct NodeOutput.Data recentPrice) + ``` + +#### max + + ```solidity + function max(struct NodeOutput.Data[] parentNodeOutputs) internal pure returns (struct NodeOutput.Data maxPrice) + ``` + +#### min + + ```solidity + function min(struct NodeOutput.Data[] parentNodeOutputs) internal pure returns (struct NodeOutput.Data minPrice) + ``` + +#### mul + + ```solidity + function mul(struct NodeOutput.Data[] parentNodeOutputs) internal pure returns (struct NodeOutput.Data mulPrice) + ``` + +#### div + + ```solidity + function div(struct NodeOutput.Data[] parentNodeOutputs) internal pure returns (struct NodeOutput.Data divPrice) + ``` + +#### quickSort + + ```solidity + function quickSort(struct NodeOutput.Data[] arr, int256 left, int256 right) internal pure + ``` + +#### isValid + + ```solidity + function isValid(struct NodeDefinition.Data nodeDefinition) internal pure returns (bool valid) + ``` + +### StalenessCircuitBreakerNode + +#### process + + ```solidity + function process(struct NodeOutput.Data[] parentNodeOutputs, bytes parameters) internal view returns (struct NodeOutput.Data nodeOutput) + ``` + +#### isValid + + ```solidity + function isValid(struct NodeDefinition.Data nodeDefinition) internal pure returns (bool valid) + ``` + +### UniswapNode + +#### process + + ```solidity + function process(bytes parameters) internal view returns (struct NodeOutput.Data nodeOutput) + ``` + +#### getQuoteAtTick + + ```solidity + function getQuoteAtTick(int24 tick, uint256 baseAmount, address baseToken, address quoteToken) internal pure returns (uint256 quoteAmount) + ``` + +#### isValid + + ```solidity + function isValid(struct NodeDefinition.Data nodeDefinition) internal view returns (bool valid) + ``` + diff --git a/markets/perps-market/docs/index.md b/markets/perps-market/docs/index.md index b4289806f6..24396c2872 100644 --- a/markets/perps-market/docs/index.md +++ b/markets/perps-market/docs/index.md @@ -1,288 +1,559 @@ -# Solidity API +### Async Order Module -## Account Module - -### modifyCollateral +#### commitOrder ```solidity - function modifyCollateral(uint128 accountId, uint128 synthMarketId, int256 amountDelta) external + function commitOrder(struct AsyncOrder.OrderCommitmentRequest commitment) external returns (struct AsyncOrder.Data retOrder, uint256 fees) ``` -### totalCollateralValue + Commit an async order via this function - ```solidity - function totalCollateralValue(uint128 accountId) external view returns (uint256) - ``` +**Parameters** +* `commitment` (*struct AsyncOrder.OrderCommitmentRequest*) - Order commitment data (see AsyncOrder.OrderCommitmentRequest struct). -### totalAccountOpenInterest +**Returns** +* `retOrder` (*struct AsyncOrder.Data*) - order details (see AsyncOrder.Data struct). +* `fees` (*uint256*) - order fees (protocol + settler) +#### getOrder ```solidity - function totalAccountOpenInterest(uint128 accountId) external view returns (uint256) + function getOrder(uint128 accountId) external returns (struct AsyncOrder.Data order) ``` -### getOpenPosition + Get async order claim details + +**Parameters** +* `accountId` (*uint128*) - id of the account. + +**Returns** +* `order` (*struct AsyncOrder.Data*) - async order claim details (see AsyncOrder.Data struct). +#### computeOrderFees ```solidity - function getOpenPosition(uint128 accountId, uint128 marketId) external view returns (int256, int256, int256) + function computeOrderFees(uint128 marketId, int128 sizeDelta) external view returns (uint256 orderFees) ``` -### getAsyncOrderClaim + Simulates what the order fee would be for the given market with the specified size. + + Note that this does not include the settlement reward fee, which is based on the strategy type used + +**Parameters** +* `marketId` (*uint128*) - id of the market. +* `sizeDelta` (*int128*) - size of position. + +**Returns** +* `orderFees` (*uint256*) - incurred fees. + +#### OrderCommitted ```solidity - function getAsyncOrderClaim(uint128 accountId, uint128 marketId) external view returns (struct AsyncOrder.Data) + event OrderCommitted(uint128 marketId, uint128 accountId, enum SettlementStrategy.Type orderType, int128 sizeDelta, uint256 acceptablePrice, uint256 settlementTime, uint256 expirationTime, bytes32 trackingCode, address sender) ``` - Get async order claim details + Gets fired when a new order is committed. **Parameters** -* `accountId` (*uint128*) - id of the account. * `marketId` (*uint128*) - Id of the market used for the trade. +* `accountId` (*uint128*) - Id of the account used for the trade. +* `orderType` (*enum SettlementStrategy.Type*) - Should send 0 (at time of writing) that correlates to the transaction type enum defined in SettlementStrategy.Type. +* `sizeDelta` (*int128*) - requested change in size of the order sent by the user. +* `acceptablePrice` (*uint256*) - maximum or minimum, depending on the sizeDelta direction, accepted price to settle the order, set by the user. +* `settlementTime` (*uint256*) - Time at which the order can be settled. +* `expirationTime` (*uint256*) - Time at which the order expired. +* `trackingCode` (*bytes32*) - Optional code for integrator tracking purposes. +* `sender` (*address*) - address of the sender of the order. Authorized to commit by account owner. -**Returns** -* `[0]` (*struct AsyncOrder.Data*) - asyncOrderClaim claim details (see AsyncOrder.Data struct). -### getAvailableMargin +### Async Order Settlement Module + +#### settle ```solidity - function getAvailableMargin(uint128 accountId) external view returns (int256) + function settle(uint128 accountId) external view ``` -### getCollateralAmount + Settles an offchain order. It's expected to revert with the OffchainLookup error with the data needed to perform the offchain lookup. + +**Parameters** +* `accountId` (*uint128*) - Id of the account used for the trade. + +#### settlePythOrder ```solidity - function getCollateralAmount(uint128 accountId, uint128 synthMarketId) external view returns (uint256) + function settlePythOrder(bytes result, bytes extraData) external payable ``` -### CollateralModified + Settles an offchain order using the offchain retrieved data from pyth. + +**Parameters** +* `result` (*bytes*) - the blob of data retrieved offchain. +* `extraData` (*bytes*) - Extra data from OffchainLookupData. + +#### OrderSettled ```solidity - event CollateralModified(uint128 accountId, uint128 synthMarketId, int256 amountDelta, address sender) + event OrderSettled(uint128 marketId, uint128 accountId, uint256 fillPrice, int256 pnl, int128 sizeDelta, int128 newSize, uint256 totalFees, uint256 referralFees, uint256 collectedFees, uint256 settlementReward, bytes32 trackingCode, address settler) ``` -## Async Order Module + Gets fired when a new order is settled. -### commitOrder +**Parameters** +* `marketId` (*uint128*) - Id of the market used for the trade. +* `accountId` (*uint128*) - Id of the account used for the trade. +* `fillPrice` (*uint256*) - Price at which the order was settled. +* `pnl` (*int256*) - +* `sizeDelta` (*int128*) - Size delta from order. +* `newSize` (*int128*) - New size of the position after settlement. +* `totalFees` (*uint256*) - Amount of fees collected by the protocol. +* `referralFees` (*uint256*) - Amount of fees collected by the referrer. +* `collectedFees` (*uint256*) - Amount of fees collected by fee collector. +* `settlementReward` (*uint256*) - Amount of fees collected by the settler. +* `trackingCode` (*bytes32*) - Optional code for integrator tracking purposes. +* `settler` (*address*) - address of the settler of the order. + +### Collateral Module + +#### setMaxCollateralAmount ```solidity - function commitOrder(struct AsyncOrder.OrderCommitmentRequest commitment) external returns (struct AsyncOrder.Data retOrder, uint256 fees) + function setMaxCollateralAmount(uint128 synthMarketId, uint256 collateralAmount) external ``` -### getOrder + Set the max collateral amoutn via this function + +**Parameters** +* `synthMarketId` (*uint128*) - Synth market id, 0 for snxUSD. +* `collateralAmount` (*uint256*) - max amount that for the synth + +#### MaxCollateralSet ```solidity - function getOrder(uint128 marketId, uint128 accountId) external returns (struct AsyncOrder.Data) + event MaxCollateralSet(uint128 synthMarketId, uint256 collateralAmount) ``` -### cancelOrder + Gets fired when max collateral amount for synth collateral for the system is set by owner. + +**Parameters** +* `synthMarketId` (*uint128*) - Synth market id, 0 for snxUSD. +* `collateralAmount` (*uint256*) - max amount that was set for the synth + +### Global Perps Market Module + +#### setMaxCollateralAmount ```solidity - function cancelOrder(uint128 marketId, uint128 accountId) external + function setMaxCollateralAmount(uint128 synthMarketId, uint256 collateralAmount) external ``` -### OrderCommitted + Sets the max collateral amount for a specific synth market. + +**Parameters** +* `synthMarketId` (*uint128*) - Synth market id, 0 for snxUSD. +* `collateralAmount` (*uint256*) - Max collateral amount to set for the synth market id. + +#### getMaxCollateralAmount ```solidity - event OrderCommitted(uint128 marketId, uint128 accountId, enum SettlementStrategy.Type orderType, int128 sizeDelta, uint256 acceptablePrice, uint256 settlementTime, uint256 expirationTime, bytes32 trackingCode, address sender) + function getMaxCollateralAmount(uint128 synthMarketId) external view returns (uint256) ``` -### OrderCanceled + Gets the max collateral amount for a specific synth market. + +**Parameters** +* `synthMarketId` (*uint128*) - Synth market id, 0 for snxUSD. + +**Returns** +* `[0]` (*uint256*) - maxCollateralAmount max collateral amount of the specified synth market id +#### setSynthDeductionPriority ```solidity - event OrderCanceled(uint128 marketId, uint128 accountId, uint256 settlementTime, uint256 acceptablePrice) + function setSynthDeductionPriority(uint128[] newSynthDeductionPriority) external ``` -## Async Order Settlement Module + Sets the synth deduction priority ordered list. -### settle + The synth deduction priority is used to determine the order in which synths are deducted from an account. Id 0 is snxUSD and should be first in the list. + +**Parameters** +* `newSynthDeductionPriority` (*uint128[]*) - Ordered array of synth market ids for deduction priority. + +#### getSynthDeductionPriority ```solidity - function settle(uint128 marketId, uint128 accountId) external view + function getSynthDeductionPriority() external view returns (uint128[]) ``` -### settlePythOrder + Gets the synth deduction priority ordered list. + + The synth deduction priority is used to determine the order in which synths are deducted from an account. Id 0 is snxUSD and should be first in the list. + +**Returns** +* `[0]` (*uint128[]*) - synthDeductionPriority Ordered array of synth market ids for deduction priority. +#### setLiquidationRewardGuards ```solidity - function settlePythOrder(bytes result, bytes extraData) external payable + function setLiquidationRewardGuards(uint256 minLiquidationRewardUsd, uint256 maxLiquidationRewardUsd) external ``` -### OrderSettled + Sets the liquidation reward guard (min and max). + +**Parameters** +* `minLiquidationRewardUsd` (*uint256*) - Minimum liquidation reward expressed as USD value. +* `maxLiquidationRewardUsd` (*uint256*) - Maximum liquidation reward expressed as USD value. + +#### getLiquidationRewardGuards ```solidity - event OrderSettled(uint128 marketId, uint128 accountId, uint256 fillPrice, int256 accountPnlRealized, int128 newSize, uint256 collectedFees, uint256 settelementReward, bytes32 trackingCode, address settler) + function getLiquidationRewardGuards() external view returns (uint256 minLiquidationRewardUsd, uint256 maxLiquidationRewardUsd) ``` -## Collateral Module + Gets the liquidation reward guard (min and max). -### setMaxCollateralAmount +**Returns** +* `minLiquidationRewardUsd` (*uint256*) - Minimum liquidation reward expressed as USD value. +* `maxLiquidationRewardUsd` (*uint256*) - Maximum liquidation reward expressed as USD value. +#### totalGlobalCollateralValue ```solidity - function setMaxCollateralAmount(uint128 synthId, uint256 maxCollateralAmount) external + function totalGlobalCollateralValue() external view returns (uint256 totalCollateralValue) ``` -### MaxCollateralSet + Gets the total collateral value of all deposited collateral from all traders. + +**Returns** +* `totalCollateralValue` (*uint256*) - value of all collateral +#### setFeeCollector ```solidity - event MaxCollateralSet(uint128 synthId, uint256 maxCollateralAmount) + function setFeeCollector(address feeCollector) external ``` - Gets fired when max collateral amount for synth is set by owner. + Sets the fee collector contract. -**Parameters** -* `synthId` (*uint128*) - Synth market id, 0 for snxUSD. -* `maxCollateralAmount` (*uint256*) - max amount that was set for the synth + must conform to the IFeeCollector interface -## Global Perps Market Module +**Parameters** +* `feeCollector` (*address*) - address of the fee collector contract -### getMaxCollateralAmount +#### getFeeCollector ```solidity - function getMaxCollateralAmount(uint128 synthMarketId) external view returns (uint256) + function getFeeCollector() external view returns (address feeCollector) ``` -### setMaxCollateralAmount + Gets the configured feeCollector contract + +**Returns** +* `feeCollector` (*address*) - address of the fee collector contract +#### updateReferrerShare ```solidity - function setMaxCollateralAmount(uint128 synthMarketId, uint256 collateralAmount) external + function updateReferrerShare(address referrer, uint256 shareRatioD18) external ``` -### setSynthDeductionPriority + Update the referral share percentage for a referrer - ```solidity - function setSynthDeductionPriority(uint128[] newSynthDeductionPriority) external - ``` +**Parameters** +* `referrer` (*address*) - The address of the referrer +* `shareRatioD18` (*uint256*) - The new share percentage for the referrer -### getSynthDeductionPriority +#### getReferrerShare ```solidity - function getSynthDeductionPriority() external view returns (uint128[]) + function getReferrerShare(address referrer) external returns (uint256 shareRatioD18) ``` -### setLiquidationRewardGuards + get the referral share percentage for the specified referrer + +**Parameters** +* `referrer` (*address*) - The address of the referrer + +**Returns** +* `shareRatioD18` (*uint256*) - The configured share percentage for the referrer + +#### MaxCollateralAmountSet ```solidity - function setLiquidationRewardGuards(uint256 minLiquidationRewardUsd, uint256 maxLiquidationRewardUsd) external + event MaxCollateralAmountSet(uint128 synthMarketId, uint256 collateralAmount) ``` -### getLiquidationRewardGuards + Gets fired when max collateral amount for synth for all the markets is set by owner. + +**Parameters** +* `synthMarketId` (*uint128*) - Synth market id, 0 for snxUSD. +* `collateralAmount` (*uint256*) - max amount that was set for the synth + +#### SynthDeductionPrioritySet ```solidity - function getLiquidationRewardGuards() external view returns (uint256 minLiquidationRewardUsd, uint256 maxLiquidationRewardUsd) + event SynthDeductionPrioritySet(uint128[] newSynthDeductionPriority) ``` -### MaxCollateralAmountSet + Gets fired when the synth deduction priority is updated by owner. + +**Parameters** +* `newSynthDeductionPriority` (*uint128[]*) - new synth id priority order for deductions. + +#### LiquidationRewardGuardsSet ```solidity - event MaxCollateralAmountSet(uint128 synthMarketId, uint256 collateralAmount) + event LiquidationRewardGuardsSet(uint256 minLiquidationRewardUsd, uint256 maxLiquidationRewardUsd) ``` -### SynthDeductionPrioritySet + Gets fired when liquidation reward guard is set or updated. + +**Parameters** +* `minLiquidationRewardUsd` (*uint256*) - Minimum liquidation reward expressed as USD value. +* `maxLiquidationRewardUsd` (*uint256*) - Maximum liquidation reward expressed as USD value. + +#### FeeCollectorSet ```solidity - event SynthDeductionPrioritySet(uint128[] newSynthDeductionPriority) + event FeeCollectorSet(address feeCollector) ``` -### LiquidationRewardGuardsSet + emitted when custom fee collector is set + +**Parameters** +* `feeCollector` (*address*) - the address of the fee collector to set. + +#### ReferrerShareUpdated ```solidity - event LiquidationRewardGuardsSet(uint256 minLiquidationRewardUsd, uint256 maxLiquidationRewardUsd) + event ReferrerShareUpdated(address referrer, uint256 shareRatioD18) ``` -## Limit Order Module + Emitted when the share percentage for a referrer address has been updated. + +**Parameters** +* `referrer` (*address*) - The address of the referrer +* `shareRatioD18` (*uint256*) - The new share ratio for the referrer -## Liquidation Module +### Liquidation Module -### liquidate +#### liquidate ```solidity function liquidate(uint128 accountId) external ``` -### liquidateFlagged +#### liquidateFlagged ```solidity function liquidateFlagged() external ``` -## Market Configuration Module +#### PositionLiquidated + + ```solidity + event PositionLiquidated(uint128 accountId, uint128 marketId, uint256 amountLiquidated, int128 currentPositionSize) + ``` + +#### AccountLiquidated + + ```solidity + event AccountLiquidated(uint128 accountId, uint256 reward, bool fullLiquidation) + ``` + +### Market Configuration Module -### addSettlementStrategy +#### addSettlementStrategy ```solidity function addSettlementStrategy(uint128 marketId, struct SettlementStrategy.Data strategy) external returns (uint256 strategyId) ``` -### setOrderFees + Add a new settlement strategy with this function. + +**Parameters** +* `marketId` (*uint128*) - id of the market to add the settlement strategy. +* `strategy` (*struct SettlementStrategy.Data*) - strategy details (see SettlementStrategy.Data struct). + +**Returns** +* `strategyId` (*uint256*) - id of the new settlement strategy. +#### setOrderFees ```solidity function setOrderFees(uint128 marketId, uint256 makerFeeRatio, uint256 takerFeeRatio) external ``` -### setFundingParameters + Set order fees for a market with this function. + +**Parameters** +* `marketId` (*uint128*) - id of the market to set order fees. +* `makerFeeRatio` (*uint256*) - the maker fee ratio. +* `takerFeeRatio` (*uint256*) - the taker fee ratio. + +#### updatePriceData + + ```solidity + function updatePriceData(uint128 perpsMarketId, bytes32 feedId) external + ``` + + Set node id for perps market + +**Parameters** +* `perpsMarketId` (*uint128*) - id of the market to set price feed. +* `feedId` (*bytes32*) - the node feed id + +#### setFundingParameters ```solidity function setFundingParameters(uint128 marketId, uint256 skewScale, uint256 maxFundingVelocity) external ``` -### setLiquidationParameters + Set funding parameters for a market with this function. + +**Parameters** +* `marketId` (*uint128*) - id of the market to set funding parameters. +* `skewScale` (*uint256*) - the skew scale. +* `maxFundingVelocity` (*uint256*) - the max funding velocity. + +#### setLiquidationParameters ```solidity - function setLiquidationParameters(uint128 marketId, uint256 initialMarginRatioD18, uint256 maintenanceMarginRatioD18, uint256 liquidationRewardRatioD18, uint256 maxLiquidationLimitAccumulationMultiplier, uint256 maxSecondsInLiquidationWindow, uint256 minimumPositionMargin) external + function setLiquidationParameters(uint128 marketId, uint256 initialMarginRatioD18, uint256 minimumInitialMarginRatioD18, uint256 maintenanceMarginScalarD18, uint256 liquidationRewardRatioD18, uint256 maxLiquidationLimitAccumulationMultiplier, uint256 maxSecondsInLiquidationWindow, uint256 minimumPositionMargin) external ``` -### setMaxMarketValue + Set liquidation parameters for a market with this function. + +**Parameters** +* `marketId` (*uint128*) - id of the market to set liquidation parameters. +* `initialMarginRatioD18` (*uint256*) - the initial margin ratio (as decimal with 18 digits precision). +* `minimumInitialMarginRatioD18` (*uint256*) - the minimum initial margin ratio (as decimal with 18 digits precision). +* `maintenanceMarginScalarD18` (*uint256*) - the maintenance margin scalar relative to the initial margin ratio (as decimal with 18 digits precision). +* `liquidationRewardRatioD18` (*uint256*) - the liquidation reward ratio (as decimal with 18 digits precision). +* `maxLiquidationLimitAccumulationMultiplier` (*uint256*) - the max liquidation limit accumulation multiplier. +* `maxSecondsInLiquidationWindow` (*uint256*) - the max seconds in liquidation window (used together with the acc multiplier to get max liquidation per window). +* `minimumPositionMargin` (*uint256*) - the minimum position margin. + +#### setMaxMarketSize ```solidity - function setMaxMarketValue(uint128 marketId, uint256 maxMarketValue) external + function setMaxMarketSize(uint128 marketId, uint256 maxMarketSize) external ``` -### setLockedOiRatio + Set the max size of an specific market with this function. + + This controls the maximum open interest a market can have on either side (Long | Short). So the total Open Interest (with zero skew) for a market can be up to max market size * 2. + +**Parameters** +* `marketId` (*uint128*) - id of the market to set the max market value. +* `maxMarketSize` (*uint256*) - the max market size in market asset units. + +#### setLockedOiRatio ```solidity function setLockedOiRatio(uint128 marketId, uint256 lockedOiRatioD18) external ``` -### setSettlementStrategyEnabled + Set the locked OI Ratio for a market with this function. + +**Parameters** +* `marketId` (*uint128*) - id of the market to set locked OI ratio. +* `lockedOiRatioD18` (*uint256*) - the locked OI ratio skew scale (as decimal with 18 digits precision). + +#### setSettlementStrategyEnabled ```solidity function setSettlementStrategyEnabled(uint128 marketId, uint256 strategyId, bool enabled) external ``` -### getSettlementStrategy + Enable or disable a settlement strategy for a market with this function. + +**Parameters** +* `marketId` (*uint128*) - id of the market. +* `strategyId` (*uint256*) - the specific strategy. +* `enabled` (*bool*) - whether the strategy is enabled or disabled. + +#### getSettlementStrategy ```solidity function getSettlementStrategy(uint128 marketId, uint256 strategyId) external view returns (struct SettlementStrategy.Data settlementStrategy) ``` -### getLiquidationParameters + Gets the settlement strategy details. + +**Parameters** +* `marketId` (*uint128*) - id of the market. +* `strategyId` (*uint256*) - id of the settlement strategy. + +**Returns** +* `settlementStrategy` (*struct SettlementStrategy.Data*) - strategy details (see SettlementStrategy.Data struct). +#### getLiquidationParameters ```solidity - function getLiquidationParameters(uint128 marketId) external view returns (uint256 initialMarginRatioD18, uint256 maintenanceMarginRatioD18, uint256 liquidationRewardRatioD18, uint256 maxLiquidationLimitAccumulationMultiplier, uint256 maxSecondsInLiquidationWindow) + function getLiquidationParameters(uint128 marketId) external view returns (uint256 initialMarginRatioD18, uint256 minimumInitialMarginRatioD18, uint256 maintenanceMarginScalarD18, uint256 liquidationRewardRatioD18, uint256 maxLiquidationLimitAccumulationMultiplier, uint256 maxSecondsInLiquidationWindow, uint256 minimumPositionMargin) ``` -### getFundingParameters + Gets liquidation parameters details of a market. + +**Parameters** +* `marketId` (*uint128*) - id of the market. + +**Returns** +* `initialMarginRatioD18` (*uint256*) - the initial margin ratio (as decimal with 18 digits precision). +* `minimumInitialMarginRatioD18` (*uint256*) - the minimum initial margin ratio (as decimal with 18 digits precision). +* `maintenanceMarginScalarD18` (*uint256*) - the maintenance margin scalar relative to the initial margin ratio (as decimal with 18 digits precision). +* `liquidationRewardRatioD18` (*uint256*) - the liquidation reward ratio (as decimal with 18 digits precision). +* `maxLiquidationLimitAccumulationMultiplier` (*uint256*) - the max liquidation limit accumulation multiplier. +* `maxSecondsInLiquidationWindow` (*uint256*) - the max seconds in liquidation window (used together with the acc multiplier to get max liquidation per window). +* `minimumPositionMargin` (*uint256*) - the minimum position margin. +#### getFundingParameters ```solidity function getFundingParameters(uint128 marketId) external view returns (uint256 skewScale, uint256 maxFundingVelocity) ``` -### getMaxMarketValue + Gets funding parameters of a market. + +**Parameters** +* `marketId` (*uint128*) - id of the market. + +**Returns** +* `skewScale` (*uint256*) - the skew scale. +* `maxFundingVelocity` (*uint256*) - the max funding velocity. +#### getMaxMarketSize ```solidity - function getMaxMarketValue(uint128 marketId) external view returns (uint256 maxMarketValue) + function getMaxMarketSize(uint128 marketId) external view returns (uint256 maxMarketSize) ``` -### getOrderFees + Gets the max size of an specific market. + +**Parameters** +* `marketId` (*uint128*) - id of the market. + +**Returns** +* `maxMarketSize` (*uint256*) - the max market size in market asset units. +#### getOrderFees ```solidity - function getOrderFees(uint128 marketId) external view returns (uint256 makerFee, uint256 takerFee) + function getOrderFees(uint128 marketId) external view returns (uint256 makerFeeRatio, uint256 takerFeeRatio) ``` -### getLockedOiRatioD18 + Gets the order fees of a market. + +**Parameters** +* `marketId` (*uint128*) - id of the market. + +**Returns** +* `makerFeeRatio` (*uint256*) - the maker fee ratio. +* `takerFeeRatio` (*uint256*) - the taker fee ratio. +#### getLockedOiRatio ```solidity - function getLockedOiRatioD18(uint128 marketId) external view returns (uint256 lockedOiRatioD18) + function getLockedOiRatio(uint128 marketId) external view returns (uint256 lockedOiRatioD18) ``` -### SettlementStrategyAdded + Gets the locked OI ratio of a market. + +**Parameters** +* `marketId` (*uint128*) - id of the market. + +**Returns** +* `lockedOiRatioD18` (*uint256*) - the locked OI ratio skew scale (as decimal with 18 digits precision). + +#### SettlementStrategyAdded ```solidity event SettlementStrategyAdded(uint128 marketId, struct SettlementStrategy.Data strategy, uint256 strategyId) @@ -295,101 +566,271 @@ * `strategy` (*struct SettlementStrategy.Data*) - the strategy configuration. * `strategyId` (*uint256*) - the newly created settlement strategy id. -### OrderFeesSet +#### MarketPriceDataUpdated + + ```solidity + event MarketPriceDataUpdated(uint128 marketId, bytes32 feedId) + ``` + + Gets fired when feed id for perps market is updated. + +**Parameters** +* `marketId` (*uint128*) - id of perps market +* `feedId` (*bytes32*) - oracle node id + +#### OrderFeesSet ```solidity event OrderFeesSet(uint128 marketId, uint256 makerFeeRatio, uint256 takerFeeRatio) ``` -### FundingParametersSet + Gets fired when order fees are updated. + +**Parameters** +* `marketId` (*uint128*) - udpates fees to this specific market. +* `makerFeeRatio` (*uint256*) - the maker fee ratio. +* `takerFeeRatio` (*uint256*) - the taker fee ratio. + +#### FundingParametersSet ```solidity event FundingParametersSet(uint128 marketId, uint256 skewScale, uint256 maxFundingVelocity) ``` -### LiquidationParametersSet + Gets fired when funding parameters are updated. + +**Parameters** +* `marketId` (*uint128*) - udpates funding parameters to this specific market. +* `skewScale` (*uint256*) - the skew scale. +* `maxFundingVelocity` (*uint256*) - the max funding velocity. + +#### LiquidationParametersSet ```solidity - event LiquidationParametersSet(uint128 marketId, uint256 initialMarginRatioD18, uint256 maintenanceMarginRatioD18, uint256 liquidationRewardRatioD18, uint256 maxLiquidationLimitAccumulationMultiplier, uint256 maxSecondsInLiquidationWindow, uint256 minimumPositionMargin) + event LiquidationParametersSet(uint128 marketId, uint256 initialMarginRatioD18, uint256 maintenanceMarginRatioD18, uint256 minimumInitialMarginRatioD18, uint256 liquidationRewardRatioD18, uint256 maxLiquidationLimitAccumulationMultiplier, uint256 maxSecondsInLiquidationWindow, uint256 minimumPositionMargin) ``` -### MaxMarketValueSet + Gets fired when liquidation parameters are updated. + +**Parameters** +* `marketId` (*uint128*) - udpates funding parameters to this specific market. +* `initialMarginRatioD18` (*uint256*) - the initial margin ratio (as decimal with 18 digits precision). +* `maintenanceMarginRatioD18` (*uint256*) - the maintenance margin ratio (as decimal with 18 digits precision). +* `minimumInitialMarginRatioD18` (*uint256*) - +* `liquidationRewardRatioD18` (*uint256*) - the liquidation reward ratio (as decimal with 18 digits precision). +* `maxLiquidationLimitAccumulationMultiplier` (*uint256*) - the max liquidation limit accumulation multiplier. +* `maxSecondsInLiquidationWindow` (*uint256*) - the max seconds in liquidation window (used together with the acc multiplier to get max liquidation per window). +* `minimumPositionMargin` (*uint256*) - the minimum position margin. + +#### MaxMarketSizeSet ```solidity - event MaxMarketValueSet(uint128 marketId, uint256 maxMarketValue) + event MaxMarketSizeSet(uint128 marketId, uint256 maxMarketSize) ``` -### LockedOiRatioD18Set + Gets fired when max market value is updated. + +**Parameters** +* `marketId` (*uint128*) - udpates funding parameters to this specific market. +* `maxMarketSize` (*uint256*) - the max market value. + +#### LockedOiRatioSet ```solidity - event LockedOiRatioD18Set(uint128 marketId, uint256 lockedOiRatioD18) + event LockedOiRatioSet(uint128 marketId, uint256 lockedOiRatioD18) ``` -### SettlementStrategyEnabled + Gets fired when locked oi ratio is updated. + +**Parameters** +* `marketId` (*uint128*) - udpates funding parameters to this specific market. +* `lockedOiRatioD18` (*uint256*) - the locked OI ratio skew scale (as decimal with 18 digits precision). + +#### SettlementStrategyEnabled ```solidity event SettlementStrategyEnabled(uint128 marketId, uint256 strategyId, bool enabled) ``` -## IMarketEvents + Gets fired when a settlement strategy is enabled or disabled. -### MarketUpdated +**Parameters** +* `marketId` (*uint128*) - udpates funding parameters to this specific market. +* `strategyId` (*uint256*) - the specific strategy. +* `enabled` (*bool*) - whether the strategy is enabled or disabled. + +### IMarketEvents + +#### MarketUpdated ```solidity - event MarketUpdated(uint128 marketId, int256 skew, uint256 size, int256 sizeDelta, int256 currentFundingRate, int256 currentFundingVelocity) + event MarketUpdated(uint128 marketId, uint256 price, int256 skew, uint256 size, int256 sizeDelta, int256 currentFundingRate, int256 currentFundingVelocity) ``` -## Perps Market Factory Module + Gets fired when the size of a market is updated by new orders or liquidations. + +**Parameters** +* `marketId` (*uint128*) - Id of the market used for the trade. +* `price` (*uint256*) - Price at the time of this event. +* `skew` (*int256*) - Market skew at the time of the trade. Positive values mean more longs. +* `size` (*uint256*) - Size of the entire market after settlement. +* `sizeDelta` (*int256*) - Change in market size during this update. +* `currentFundingRate` (*int256*) - The current funding rate of this market (0.001 = 0.1% per day) +* `currentFundingVelocity` (*int256*) - The current rate of change of the funding rate (0.001 = +0.1% per day) -### setSynthetix +### Perps Account Module + +#### modifyCollateral ```solidity - function setSynthetix(contract ISynthetixSystem synthetix) external + function modifyCollateral(uint128 accountId, uint128 synthMarketId, int256 amountDelta) external ``` -### setSpotMarket + Modify the collateral delegated to the account. + +**Parameters** +* `accountId` (*uint128*) - Id of the account. +* `synthMarketId` (*uint128*) - Id of the synth market used as collateral. Synth market id, 0 for snxUSD. +* `amountDelta` (*int256*) - requested change in amount of collateral delegated to the account. + +#### getCollateralAmount ```solidity - function setSpotMarket(contract ISpotMarketSystem spotMarket) external + function getCollateralAmount(uint128 accountId, uint128 synthMarketId) external view returns (uint256) ``` -### createMarket + Gets the account's collateral value for a specific collateral. + +**Parameters** +* `accountId` (*uint128*) - Id of the account. +* `synthMarketId` (*uint128*) - Id of the synth market used as collateral. Synth market id, 0 for snxUSD. + +**Returns** +* `[0]` (*uint256*) - collateralValue collateral value of the account. +#### totalCollateralValue ```solidity - function createMarket(string marketName, string marketSymbol, address marketOwner) external returns (uint128) + function totalCollateralValue(uint128 accountId) external view returns (uint256) ``` -### symbol + Gets the account's total collateral value. + +**Parameters** +* `accountId` (*uint128*) - Id of the account. + +**Returns** +* `[0]` (*uint256*) - collateralValue total collateral value of the account. USD denominated. +#### totalAccountOpenInterest ```solidity - function symbol(uint128 marketId) external view returns (string) + function totalAccountOpenInterest(uint128 accountId) external view returns (uint256) ``` -### updatePriceData + Gets the account's total open interest value. + +**Parameters** +* `accountId` (*uint128*) - Id of the account. + +**Returns** +* `[0]` (*uint256*) - openInterestValue total open interest value of the account. +#### getOpenPosition ```solidity - function updatePriceData(uint128 perpsMarketId, bytes32 feedId) external + function getOpenPosition(uint128 accountId, uint128 marketId) external view returns (int256 totalPnl, int256 accruedFunding, int128 positionSize) ``` -### nominateMarketOwner + Gets the details of an open position. + +**Parameters** +* `accountId` (*uint128*) - Id of the account. +* `marketId` (*uint128*) - Id of the position market. + +**Returns** +* `totalPnl` (*int256*) - pnl of the entire position including funding. +* `accruedFunding` (*int256*) - accrued funding of the position. +* `positionSize` (*int128*) - size of the position. +#### getAvailableMargin ```solidity - function nominateMarketOwner(uint128 perpsMarketId, address newNominatedOwner) external + function getAvailableMargin(uint128 accountId) external view returns (int256 availableMargin) ``` -### acceptMarketOwnership + Gets the available margin of an account. It can be negative due to pnl. + +**Parameters** +* `accountId` (*uint128*) - Id of the account. + +**Returns** +* `availableMargin` (*int256*) - available margin of the position. +#### getWithdrawableMargin ```solidity - function acceptMarketOwnership(uint128 perpsMarketId) external + function getWithdrawableMargin(uint128 accountId) external view returns (int256 withdrawableMargin) ``` -### getMarketOwner + Gets the exact withdrawable amount a trader has available from this account while holding the account's current positions. + +**Parameters** +* `accountId` (*uint128*) - Id of the account. + +**Returns** +* `withdrawableMargin` (*int256*) - available margin to withdraw. +#### getRequiredMargins ```solidity - function getMarketOwner(uint128 perpsMarketId) external view returns (address) + function getRequiredMargins(uint128 accountId) external view returns (uint256 requiredInitialMargin, uint256 requiredMaintenanceMargin) ``` -### name + Gets the initial/maintenance margins across all positions that an account has open. + +**Parameters** +* `accountId` (*uint128*) - Id of the account. + +**Returns** +* `requiredInitialMargin` (*uint256*) - initial margin req (used when withdrawing collateral). +* `requiredMaintenanceMargin` (*uint256*) - maintenance margin req (used to determine liquidation threshold). + +#### CollateralModified + + ```solidity + event CollateralModified(uint128 accountId, uint128 synthMarketId, int256 amountDelta, address sender) + ``` + + Gets fired when an account colateral is modified. + +**Parameters** +* `accountId` (*uint128*) - Id of the account. +* `synthMarketId` (*uint128*) - Id of the synth market used as collateral. Synth market id, 0 for snxUSD. +* `amountDelta` (*int256*) - requested change in amount of collateral delegated to the account. +* `sender` (*address*) - address of the sender of the size modification. Authorized by account owner. + +### Perps Market Factory Module + +#### initializeFactory + + ```solidity + function initializeFactory() external returns (uint128) + ``` + +#### setSynthetix + + ```solidity + function setSynthetix(contract ISynthetixSystem synthetix) external + ``` + +#### setSpotMarket + + ```solidity + function setSpotMarket(contract ISpotMarketSystem spotMarket) external + ``` + +#### createMarket + + ```solidity + function createMarket(uint128 requestedMarketId, string marketName, string marketSymbol) external returns (uint128) + ``` + +#### name ```solidity function name(uint128 marketId) external view returns (string) @@ -397,15 +838,15 @@ returns a human-readable name for a given market -### reportedDebt +#### reportedDebt ```solidity function reportedDebt(uint128 marketId) external view returns (uint256) ``` - returns amount of USD that the market would try to mint256 if everything was withdrawn + returns amount of USD that the market would try to mint if everything was withdrawn -### minimumCredit +#### minimumCredit ```solidity function minimumCredit(uint128 marketId) external view returns (uint256) @@ -413,7 +854,7 @@ prevents reduction of available credit capacity by specifying this amount, for which withdrawals will be disallowed -### supportsInterface +#### supportsInterface ```solidity function supportsInterface(bytes4 interfaceID) external view returns (bool) @@ -427,75 +868,69 @@ **Returns** * `[0]` (*bool*) - True if the contract supports the specified interface. -### MarketRegistered +#### FactoryInitialized ```solidity - event MarketRegistered(uint128 perpsMarketId, address marketOwner, string marketName, string marketSymbol) + event FactoryInitialized(uint128 globalPerpsMarketId) ``` -### MarketOwnerNominated +#### MarketCreated ```solidity - event MarketOwnerNominated(uint128 perpsMarketId, address newNominatedOwner) + event MarketCreated(uint128 perpsMarketId, string marketName, string marketSymbol) ``` -### MarketOwnerChanged +### Perps Market Module - ```solidity - event MarketOwnerChanged(uint128 perpsMarketId, address oldOwner, address newOwner) - ``` - -### MarketPriceDataUpdated +#### metadata ```solidity - event MarketPriceDataUpdated(uint128 perpsMarketId, bytes32 feedId) + function metadata(uint128 marketId) external view returns (string name, string symbol) ``` -## Perps Market Module - -### skew +#### skew ```solidity function skew(uint128 marketId) external view returns (int256) ``` -### size +#### size ```solidity function size(uint128 marketId) external view returns (uint256) ``` -### maxOpenInterest +#### maxOpenInterest ```solidity function maxOpenInterest(uint128 marketId) external view returns (uint256) ``` -### currentFundingRate +#### currentFundingRate ```solidity function currentFundingRate(uint128 marketId) external view returns (int256) ``` -### currentFundingVelocity +#### currentFundingVelocity ```solidity function currentFundingVelocity(uint128 marketId) external view returns (int256) ``` -### indexPrice +#### indexPrice ```solidity function indexPrice(uint128 marketId) external view returns (uint256) ``` -### fillPrice +#### fillPrice ```solidity - function fillPrice(uint128 marketId, int256 orderSize, uint256 price) external returns (uint256) + function fillPrice(uint128 marketId, int128 orderSize, uint256 price) external returns (uint256) ``` -### getMarketSummary +#### getMarketSummary ```solidity function getMarketSummary(uint128 marketId) external view returns (struct IPerpsMarketModule.MarketSummary summary) diff --git a/markets/spot-market/docs/index.md b/markets/spot-market/docs/index.md index dfaefdabd7..53d61a318c 100644 --- a/markets/spot-market/docs/index.md +++ b/markets/spot-market/docs/index.md @@ -1,8 +1,6 @@ -# Solidity API +### Async Order Configuration Module -## Async Order Configuration Module - -### addSettlementStrategy +#### addSettlementStrategy ```solidity function addSettlementStrategy(uint128 synthMarketId, struct SettlementStrategy.Data strategy) external returns (uint256 strategyId) @@ -16,7 +14,7 @@ **Returns** * `strategyId` (*uint256*) - newly created settlement strategy id. -### setSettlementStrategyEnabled +#### setSettlementStrategyEnabled ```solidity function setSettlementStrategyEnabled(uint128 synthMarketId, uint256 strategyId, bool enabled) external @@ -31,7 +29,7 @@ * `strategyId` (*uint256*) - id of the strategy. * `enabled` (*bool*) - set enabled/disabled. -### getSettlementStrategy +#### getSettlementStrategy ```solidity function getSettlementStrategy(uint128 marketId, uint256 strategyId) external view returns (struct SettlementStrategy.Data settlementStrategy) @@ -46,7 +44,7 @@ **Returns** * `settlementStrategy` (*struct SettlementStrategy.Data*) - -### SettlementStrategyAdded +#### SettlementStrategyAdded ```solidity event SettlementStrategyAdded(uint128 synthMarketId, uint256 strategyId) @@ -58,7 +56,7 @@ * `synthMarketId` (*uint128*) - adds settlement strategy to this specific market. * `strategyId` (*uint256*) - the newly created settlement strategy id. -### SettlementStrategyUpdated +#### SettlementStrategyUpdated ```solidity event SettlementStrategyUpdated(uint128 synthMarketId, uint256 strategyId, bool enabled) @@ -73,9 +71,9 @@ * `strategyId` (*uint256*) - id of the strategy. * `enabled` (*bool*) - true/false. -## Async Order Module +### Async Order Module -### commitOrder +#### commitOrder ```solidity function commitOrder(uint128 marketId, enum Transaction.Type orderType, uint256 amountProvided, uint256 settlementStrategyId, uint256 minimumSettlementAmount, address referrer) external returns (struct AsyncOrderClaim.Data asyncOrderClaim) @@ -95,7 +93,7 @@ **Returns** * `asyncOrderClaim` (*struct AsyncOrderClaim.Data*) - claim details (see AsyncOrderClaim.Data struct). -### cancelOrder +#### cancelOrder ```solidity function cancelOrder(uint128 marketId, uint128 asyncOrderId) external @@ -111,7 +109,7 @@ needs to satisfy commitmentTime + settlementDelay + settlementDuration < block.t * `marketId` (*uint128*) - Id of the market used for the trade. * `asyncOrderId` (*uint128*) - id of the async order created during commitment. -### getAsyncOrderClaim +#### getAsyncOrderClaim ```solidity function getAsyncOrderClaim(uint128 marketId, uint128 asyncOrderId) external view returns (struct AsyncOrderClaim.Data asyncOrderClaim) @@ -126,7 +124,7 @@ needs to satisfy commitmentTime + settlementDelay + settlementDuration < block.t **Returns** * `asyncOrderClaim` (*struct AsyncOrderClaim.Data*) - claim details (see AsyncOrderClaim.Data struct). -### OrderCommitted +#### OrderCommitted ```solidity event OrderCommitted(uint128 marketId, enum Transaction.Type orderType, uint256 amountProvided, uint128 asyncOrderId, address sender, address referrer) @@ -142,7 +140,7 @@ needs to satisfy commitmentTime + settlementDelay + settlementDuration < block.t * `sender` (*address*) - trader address. * `referrer` (*address*) - Optional address of the referrer, for fee share -### OrderCancelled +#### OrderCancelled ```solidity event OrderCancelled(uint128 marketId, uint128 asyncOrderId, struct AsyncOrderClaim.Data asyncOrderClaim, address sender) @@ -156,9 +154,9 @@ needs to satisfy commitmentTime + settlementDelay + settlementDuration < block.t * `asyncOrderClaim` (*struct AsyncOrderClaim.Data*) - claim details (see AsyncOrderClaim.Data struct). * `sender` (*address*) - trader address and also the receiver of the funds. -## Async Order Settlement Module +### Async Order Settlement Module -### settleOrder +#### settleOrder ```solidity function settleOrder(uint128 marketId, uint128 asyncOrderId) external returns (uint256 finalOrderAmount, struct OrderFees.Data) @@ -176,7 +174,7 @@ if the strategy is offchain, this function will revert with OffchainLookup error **Returns** * `finalOrderAmount` (*uint256*) - amount returned to trader after fees. * `[1]` (*struct OrderFees.Data*) - OrderFees.Data breakdown of all the fees incurred for the transaction. -### settlePythOrder +#### settlePythOrder ```solidity function settlePythOrder(bytes result, bytes extraData) external payable returns (uint256 finalOrderAmount, struct OrderFees.Data fees) @@ -198,7 +196,7 @@ To determine the fee, the client should first call getUpdateFee() from Pyth's ve * `finalOrderAmount` (*uint256*) - amount returned to trader after fees. * `fees` (*struct OrderFees.Data*) - breakdown of all the fees incurred for the transaction. -### OrderSettled +#### OrderSettled ```solidity event OrderSettled(uint128 marketId, uint128 asyncOrderId, uint256 finalOrderAmount, struct OrderFees.Data fees, uint256 collectedFees, address settler, uint256 price, enum Transaction.Type orderType) @@ -216,9 +214,9 @@ To determine the fee, the client should first call getUpdateFee() from Pyth's ve * `price` (*uint256*) - * `orderType` (*enum Transaction.Type*) - -## Atomic Order Module +### Atomic Order Module -### buyExactIn +#### buyExactIn ```solidity function buyExactIn(uint128 synthMarketId, uint256 amountUsd, uint256 minAmountReceived, address referrer) external returns (uint256 synthAmount, struct OrderFees.Data fees) @@ -239,7 +237,7 @@ Uses the buyFeedId configured for the market. **Returns** * `synthAmount` (*uint256*) - Synth received on the trade based on amount provided by trader. * `fees` (*struct OrderFees.Data*) - breakdown of all the fees incurred for the transaction. -### buy +#### buy ```solidity function buy(uint128 marketId, uint256 usdAmount, uint256 minAmountReceived, address referrer) external returns (uint256 synthAmount, struct OrderFees.Data fees) @@ -256,7 +254,7 @@ Uses the buyFeedId configured for the market. **Returns** * `synthAmount` (*uint256*) - (see buyExactIn) * `fees` (*struct OrderFees.Data*) - (see buyExactIn) -### buyExactOut +#### buyExactOut ```solidity function buyExactOut(uint128 synthMarketId, uint256 synthAmount, uint256 maxUsdAmount, address referrer) external returns (uint256 usdAmountCharged, struct OrderFees.Data fees) @@ -275,7 +273,7 @@ Uses the buyFeedId configured for the market. **Returns** * `usdAmountCharged` (*uint256*) - amount of USD charged for the trade * `fees` (*struct OrderFees.Data*) - breakdown of all the fees incurred for the transaction -### quoteBuyExactIn +#### quoteBuyExactIn ```solidity function quoteBuyExactIn(uint128 synthMarketId, uint256 usdAmount) external view returns (uint256 synthAmount, struct OrderFees.Data fees) @@ -290,7 +288,7 @@ Uses the buyFeedId configured for the market. **Returns** * `synthAmount` (*uint256*) - return amount of synth given the USD amount - fees * `fees` (*struct OrderFees.Data*) - breakdown of all the quoted fees for the buy txn -### quoteBuyExactOut +#### quoteBuyExactOut ```solidity function quoteBuyExactOut(uint128 synthMarketId, uint256 synthAmount) external view returns (uint256 usdAmountCharged, struct OrderFees.Data) @@ -305,7 +303,7 @@ Uses the buyFeedId configured for the market. **Returns** * `usdAmountCharged` (*uint256*) - USD amount charged for the synth requested - fees * `[1]` (*struct OrderFees.Data*) - fees breakdown of all the quoted fees for the buy txn -### sellExactIn +#### sellExactIn ```solidity function sellExactIn(uint128 synthMarketId, uint256 sellAmount, uint256 minAmountReceived, address referrer) external returns (uint256 returnAmount, struct OrderFees.Data fees) @@ -325,7 +323,7 @@ Leftover fees not collected get deposited into the market manager to improve mar **Returns** * `returnAmount` (*uint256*) - Amount of snxUSD returned to user * `fees` (*struct OrderFees.Data*) - breakdown of all the fees incurred for the transaction. -### sellExactOut +#### sellExactOut ```solidity function sellExactOut(uint128 marketId, uint256 usdAmount, uint256 maxSynthAmount, address referrer) external returns (uint256 synthToBurn, struct OrderFees.Data fees) @@ -344,7 +342,7 @@ Leftover fees not collected get deposited into the market manager to improve mar **Returns** * `synthToBurn` (*uint256*) - amount of synth charged for the specified usd amount * `fees` (*struct OrderFees.Data*) - breakdown of all the fees incurred for the transaction -### sell +#### sell ```solidity function sell(uint128 marketId, uint256 synthAmount, uint256 minUsdAmount, address referrer) external returns (uint256 usdAmountReceived, struct OrderFees.Data fees) @@ -361,7 +359,7 @@ Leftover fees not collected get deposited into the market manager to improve mar **Returns** * `usdAmountReceived` (*uint256*) - (see sellExactIn) * `fees` (*struct OrderFees.Data*) - (see sellExactIn) -### quoteSellExactIn +#### quoteSellExactIn ```solidity function quoteSellExactIn(uint128 marketId, uint256 synthAmount) external view returns (uint256 returnAmount, struct OrderFees.Data fees) @@ -378,7 +376,7 @@ Leftover fees not collected get deposited into the market manager to improve mar **Returns** * `returnAmount` (*uint256*) - amount of USD expected back * `fees` (*struct OrderFees.Data*) - breakdown of all the quoted fees for the txn -### quoteSellExactOut +#### quoteSellExactOut ```solidity function quoteSellExactOut(uint128 marketId, uint256 usdAmount) external view returns (uint256 synthToBurn, struct OrderFees.Data fees) @@ -396,7 +394,7 @@ Leftover fees not collected get deposited into the market manager to improve mar * `synthToBurn` (*uint256*) - amount of synth expected from trader * `fees` (*struct OrderFees.Data*) - breakdown of all the quoted fees for the txn -### SynthBought +#### SynthBought ```solidity event SynthBought(uint256 synthMarketId, uint256 synthReturned, struct OrderFees.Data fees, uint256 collectedFees, address referrer, uint256 price) @@ -412,7 +410,7 @@ Leftover fees not collected get deposited into the market manager to improve mar * `referrer` (*address*) - Optional address of the referrer, for fee share * `price` (*uint256*) - -### SynthSold +#### SynthSold ```solidity event SynthSold(uint256 synthMarketId, uint256 amountReturned, struct OrderFees.Data fees, uint256 collectedFees, address referrer, uint256 price) @@ -428,9 +426,9 @@ Leftover fees not collected get deposited into the market manager to improve mar * `referrer` (*address*) - Optional address of the referrer, for fee share * `price` (*uint256*) - -## Market Configuration Module +### Market Configuration Module -### getMarketFees +#### getMarketFees ```solidity function getMarketFees(uint128 synthMarketId) external returns (uint256 atomicFixedFee, uint256 asyncFixedFee, int256 wrapFee, int256 unwrapFee) @@ -446,7 +444,7 @@ Leftover fees not collected get deposited into the market manager to improve mar * `asyncFixedFee` (*uint256*) - fixed fee amount represented in bips with 18 decimals. * `wrapFee` (*int256*) - wrapping fee in %, 18 decimals. Can be negative. * `unwrapFee` (*int256*) - unwrapping fee in %, 18 decimals. Can be negative. -### setAtomicFixedFee +#### setAtomicFixedFee ```solidity function setAtomicFixedFee(uint128 synthMarketId, uint256 atomicFixedFee) external @@ -460,7 +458,7 @@ Leftover fees not collected get deposited into the market manager to improve mar * `synthMarketId` (*uint128*) - Id of the market the fee applies to. * `atomicFixedFee` (*uint256*) - fixed fee amount represented in bips with 18 decimals. -### setAsyncFixedFee +#### setAsyncFixedFee ```solidity function setAsyncFixedFee(uint128 synthMarketId, uint256 asyncFixedFee) external @@ -474,7 +472,7 @@ Leftover fees not collected get deposited into the market manager to improve mar * `synthMarketId` (*uint128*) - Id of the market the fee applies to. * `asyncFixedFee` (*uint256*) - fixed fee amount represented in bips with 18 decimals. -### setMarketSkewScale +#### setMarketSkewScale ```solidity function setMarketSkewScale(uint128 synthMarketId, uint256 skewScale) external @@ -488,7 +486,7 @@ Leftover fees not collected get deposited into the market manager to improve mar * `synthMarketId` (*uint128*) - Id of the market the skew scale applies to. * `skewScale` (*uint256*) - max amount of synth which makes the skew 100%. the fee is derived as a % of the max value. 100% premium means outstanding synth == skewScale. -### getMarketSkewScale +#### getMarketSkewScale ```solidity function getMarketSkewScale(uint128 synthMarketId) external returns (uint256 skewScale) @@ -501,7 +499,7 @@ Leftover fees not collected get deposited into the market manager to improve mar **Returns** * `skewScale` (*uint256*) - max amount of synth which makes the skew 100%. the fee is derived as a % of the max value. 100% premium means outstanding synth == skewScale. -### setMarketUtilizationFees +#### setMarketUtilizationFees ```solidity function setMarketUtilizationFees(uint128 synthMarketId, uint256 utilizationFeeRate) external @@ -516,7 +514,7 @@ Leftover fees not collected get deposited into the market manager to improve mar * `synthMarketId` (*uint128*) - Id of the market the utilization fee applies to. * `utilizationFeeRate` (*uint256*) - the rate is represented in bips with 18 decimals and is the rate at which fee increases based on the % above 100% utilization of the delegated collateral for the market. -### getMarketUtilizationFees +#### getMarketUtilizationFees ```solidity function getMarketUtilizationFees(uint128 synthMarketId) external returns (uint256 utilizationFeeRate) @@ -531,7 +529,7 @@ Leftover fees not collected get deposited into the market manager to improve mar **Returns** * `utilizationFeeRate` (*uint256*) - the rate is represented in bips with 18 decimals and is the rate at which fee increases based on the % above 100% utilization of the delegated collateral for the market. -### setCollateralLeverage +#### setCollateralLeverage ```solidity function setCollateralLeverage(uint128 synthMarketId, uint256 collateralLeverage) external @@ -546,7 +544,7 @@ this leverage value is a value applied to delegated collateral which is compared * `synthMarketId` (*uint128*) - Id of the market the collateral leverage applies to. * `collateralLeverage` (*uint256*) - the leverage is represented as % with 18 decimals. 1 = 1x leverage -### getCollateralLeverage +#### getCollateralLeverage ```solidity function getCollateralLeverage(uint128 synthMarketId) external returns (uint256 collateralLeverage) @@ -561,7 +559,7 @@ this leverage value is a value applied to delegated collateral which is compared **Returns** * `collateralLeverage` (*uint256*) - the leverage is represented as % with 18 decimals. 1 = 1x leverage -### setCustomTransactorFees +#### setCustomTransactorFees ```solidity function setCustomTransactorFees(uint128 synthMarketId, address transactor, uint256 fixedFeeAmount) external @@ -578,7 +576,7 @@ especially useful for direct integrations where configured traders get a discoun * `transactor` (*address*) - address of the trader getting discounted fees. * `fixedFeeAmount` (*uint256*) - the fixed fee applying to the provided transactor. -### getCustomTransactorFees +#### getCustomTransactorFees ```solidity function getCustomTransactorFees(uint128 synthMarketId, address transactor) external returns (uint256 fixedFeeAmount) @@ -595,7 +593,7 @@ especially useful for direct integrations where configured traders get a discoun **Returns** * `fixedFeeAmount` (*uint256*) - the fixed fee applying to the provided transactor. -### setFeeCollector +#### setFeeCollector ```solidity function setFeeCollector(uint128 synthMarketId, address feeCollector) external @@ -611,7 +609,7 @@ if fee collector is not set, the fees are deposited into the market manager. * `synthMarketId` (*uint128*) - Id of the market the fee collector applies to. * `feeCollector` (*address*) - address of the fee collector inheriting the IFeeCollector interface. -### getFeeCollector +#### getFeeCollector ```solidity function getFeeCollector(uint128 synthMarketId) external returns (address feeCollector) @@ -624,7 +622,7 @@ if fee collector is not set, the fees are deposited into the market manager. **Returns** * `feeCollector` (*address*) - address of the fee collector inheriting the IFeeCollector interface. -### setWrapperFees +#### setWrapperFees ```solidity function setWrapperFees(uint128 synthMarketId, int256 wrapFee, int256 unwrapFee) external @@ -640,7 +638,7 @@ fees can be negative. this is a way to unwind the wrapper if needed by providin * `wrapFee` (*int256*) - wrapping fee in %, 18 decimals. Can be negative. * `unwrapFee` (*int256*) - unwrapping fee in %, 18 decimals. Can be negative. -### updateReferrerShare +#### updateReferrerShare ```solidity function updateReferrerShare(uint128 marketId, address referrer, uint256 sharePercentage) external @@ -653,7 +651,7 @@ fees can be negative. this is a way to unwind the wrapper if needed by providin * `referrer` (*address*) - The address of the referrer * `sharePercentage` (*uint256*) - The new share percentage for the referrer -### getReferrerShare +#### getReferrerShare ```solidity function getReferrerShare(uint128 marketId, address referrer) external returns (uint256 sharePercentage) @@ -668,7 +666,7 @@ fees can be negative. this is a way to unwind the wrapper if needed by providin **Returns** * `sharePercentage` (*uint256*) - The new share percentage for the referrer -### MarketUtilizationFeesSet +#### MarketUtilizationFeesSet ```solidity event MarketUtilizationFeesSet(uint256 synthMarketId, uint256 utilizationFeeRate) @@ -680,7 +678,7 @@ fees can be negative. this is a way to unwind the wrapper if needed by providin * `synthMarketId` (*uint256*) - market id * `utilizationFeeRate` (*uint256*) - utilization fee rate value -### MarketSkewScaleSet +#### MarketSkewScaleSet ```solidity event MarketSkewScaleSet(uint256 synthMarketId, uint256 skewScale) @@ -692,7 +690,7 @@ fees can be negative. this is a way to unwind the wrapper if needed by providin * `synthMarketId` (*uint256*) - market id * `skewScale` (*uint256*) - skew scale value -### CollateralLeverageSet +#### CollateralLeverageSet ```solidity event CollateralLeverageSet(uint256 synthMarketId, uint256 collateralLeverage) @@ -704,7 +702,7 @@ fees can be negative. this is a way to unwind the wrapper if needed by providin * `synthMarketId` (*uint256*) - market id * `collateralLeverage` (*uint256*) - leverage value -### AtomicFixedFeeSet +#### AtomicFixedFeeSet ```solidity event AtomicFixedFeeSet(uint256 synthMarketId, uint256 atomicFixedFee) @@ -716,7 +714,7 @@ fees can be negative. this is a way to unwind the wrapper if needed by providin * `synthMarketId` (*uint256*) - market id * `atomicFixedFee` (*uint256*) - fee value -### AsyncFixedFeeSet +#### AsyncFixedFeeSet ```solidity event AsyncFixedFeeSet(uint256 synthMarketId, uint256 asyncFixedFee) @@ -728,7 +726,7 @@ fees can be negative. this is a way to unwind the wrapper if needed by providin * `synthMarketId` (*uint256*) - market id * `asyncFixedFee` (*uint256*) - fee value -### TransactorFixedFeeSet +#### TransactorFixedFeeSet ```solidity event TransactorFixedFeeSet(uint256 synthMarketId, address transactor, uint256 fixedFeeAmount) @@ -743,7 +741,7 @@ fees can be negative. this is a way to unwind the wrapper if needed by providin * `transactor` (*address*) - fixed fee for the transactor (overrides the global fixed fee) * `fixedFeeAmount` (*uint256*) - the fixed fee for the corresponding market, and transactor -### FeeCollectorSet +#### FeeCollectorSet ```solidity event FeeCollectorSet(uint256 synthMarketId, address feeCollector) @@ -755,7 +753,7 @@ fees can be negative. this is a way to unwind the wrapper if needed by providin * `synthMarketId` (*uint256*) - Id of the market to set the collector for. * `feeCollector` (*address*) - the address of the fee collector to set. -### WrapperFeesSet +#### WrapperFeesSet ```solidity event WrapperFeesSet(uint256 synthMarketId, int256 wrapFee, int256 unwrapFee) @@ -768,22 +766,22 @@ fees can be negative. this is a way to unwind the wrapper if needed by providin * `wrapFee` (*int256*) - wrapping fee in %, 18 decimals. Can be negative. * `unwrapFee` (*int256*) - unwrapping fee in %, 18 decimals. Can be negative. -### ReferrerShareUpdated +#### ReferrerShareUpdated ```solidity event ReferrerShareUpdated(uint128 marketId, address referrer, uint256 sharePercentage) ``` - Emitted when the owner of the market has changed. + Emitted when the share percentage for a referrer address has been updated. **Parameters** * `marketId` (*uint128*) - Id of the market * `referrer` (*address*) - The address of the referrer * `sharePercentage` (*uint256*) - The new share percentage for the referrer -## Spot Market Factory Module +### Spot Market Factory Module -### setSynthetix +#### setSynthetix ```solidity function setSynthetix(contract ISynthetixSystem synthetix) external @@ -796,7 +794,7 @@ fees can be negative. this is a way to unwind the wrapper if needed by providin **Parameters** * `synthetix` (*contract ISynthetixSystem*) - synthetix v3 core system address -### setSynthImplementation +#### setSynthImplementation ```solidity function setSynthImplementation(address synthImplementation) external @@ -807,7 +805,7 @@ fees can be negative. this is a way to unwind the wrapper if needed by providin **Parameters** * `synthImplementation` (*address*) - erc20 implementation address -### createSynth +#### createSynth ```solidity function createSynth(string tokenName, string tokenSymbol, address synthOwner) external returns (uint128 synthMarketId) @@ -825,7 +823,7 @@ Sets up the market owner who can update configuration for the synth. **Returns** * `synthMarketId` (*uint128*) - id of the synth market that was created -### getSynth +#### getSynth ```solidity function getSynth(uint128 marketId) external view returns (address synthAddress) @@ -840,7 +838,7 @@ Sets up the market owner who can update configuration for the synth. **Returns** * `synthAddress` (*address*) - address of the proxy for the synth -### getSynthImpl +#### getSynthImpl ```solidity function getSynthImpl(uint128 marketId) external view returns (address implAddress) @@ -856,7 +854,7 @@ This address should not be used directly--use `getSynth` instead **Returns** * `implAddress` (*address*) - address of the proxy for the synth -### updatePriceData +#### updatePriceData ```solidity function updatePriceData(uint128 marketId, bytes32 buyFeedId, bytes32 sellFeedId) external @@ -871,7 +869,7 @@ This address should not be used directly--use `getSynth` instead * `buyFeedId` (*bytes32*) - the oracle manager buy feed node id * `sellFeedId` (*bytes32*) - the oracle manager sell feed node id -### upgradeSynthImpl +#### upgradeSynthImpl ```solidity function upgradeSynthImpl(uint128 marketId) external @@ -885,7 +883,7 @@ Anyone who is willing and able to spend the gas can call this method. **Parameters** * `marketId` (*uint128*) - id of the market -### setDecayRate +#### setDecayRate ```solidity function setDecayRate(uint128 marketId, uint256 rate) external @@ -897,7 +895,7 @@ Anyone who is willing and able to spend the gas can call this method. * `marketId` (*uint128*) - the market to update the synth decay rate for * `rate` (*uint256*) - APY to decay of the synth to decay by, as a 18 decimal ratio -### nominateMarketOwner +#### nominateMarketOwner ```solidity function nominateMarketOwner(uint128 synthMarketId, address newNominatedOwner) external @@ -911,7 +909,7 @@ Anyone who is willing and able to spend the gas can call this method. * `synthMarketId` (*uint128*) - synth market id value * `newNominatedOwner` (*address*) - The address that is to become nominated. -### acceptMarketOwnership +#### acceptMarketOwnership ```solidity function acceptMarketOwnership(uint128 synthMarketId) external @@ -924,7 +922,7 @@ Anyone who is willing and able to spend the gas can call this method. **Parameters** * `synthMarketId` (*uint128*) - synth market id value -### renounceMarketNomination +#### renounceMarketNomination ```solidity function renounceMarketNomination(uint128 synthMarketId) external @@ -937,7 +935,7 @@ Anyone who is willing and able to spend the gas can call this method. **Parameters** * `synthMarketId` (*uint128*) - synth market id value -### getMarketOwner +#### getMarketOwner ```solidity function getMarketOwner(uint128 synthMarketId) external view returns (address) @@ -948,7 +946,7 @@ Anyone who is willing and able to spend the gas can call this method. **Parameters** * `synthMarketId` (*uint128*) - synth market id value -### name +#### name ```solidity function name(uint128 marketId) external view returns (string) @@ -956,15 +954,15 @@ Anyone who is willing and able to spend the gas can call this method. returns a human-readable name for a given market -### reportedDebt +#### reportedDebt ```solidity function reportedDebt(uint128 marketId) external view returns (uint256) ``` - returns amount of USD that the market would try to mint256 if everything was withdrawn + returns amount of USD that the market would try to mint if everything was withdrawn -### minimumCredit +#### minimumCredit ```solidity function minimumCredit(uint128 marketId) external view returns (uint256) @@ -972,7 +970,7 @@ Anyone who is willing and able to spend the gas can call this method. prevents reduction of available credit capacity by specifying this amount, for which withdrawals will be disallowed -### supportsInterface +#### supportsInterface ```solidity function supportsInterface(bytes4 interfaceID) external view returns (bool) @@ -986,7 +984,7 @@ Anyone who is willing and able to spend the gas can call this method. **Returns** * `[0]` (*bool*) - True if the contract supports the specified interface. -### SynthetixSystemSet +#### SynthetixSystemSet ```solidity event SynthetixSystemSet(address synthetix, address usdTokenAddress, address oracleManager) @@ -999,7 +997,7 @@ Anyone who is willing and able to spend the gas can call this method. * `usdTokenAddress` (*address*) - address of the USDToken contract * `oracleManager` (*address*) - address of the Oracle Manager contract -### SynthImplementationSet +#### SynthImplementationSet ```solidity event SynthImplementationSet(address synthImplementation) @@ -1010,7 +1008,7 @@ Anyone who is willing and able to spend the gas can call this method. **Parameters** * `synthImplementation` (*address*) - address of the synth implementation -### SynthRegistered +#### SynthRegistered ```solidity event SynthRegistered(uint256 synthMarketId) @@ -1021,7 +1019,7 @@ Anyone who is willing and able to spend the gas can call this method. **Parameters** * `synthMarketId` (*uint256*) - Id of the synth market that was created -### SynthImplementationUpgraded +#### SynthImplementationUpgraded ```solidity event SynthImplementationUpgraded(uint256 synthMarketId, address proxy, address implementation) @@ -1034,7 +1032,7 @@ Anyone who is willing and able to spend the gas can call this method. * `proxy` (*address*) - the synth proxy servicing the latest implementation * `implementation` (*address*) - the latest implementation of the synth -### SynthPriceDataUpdated +#### SynthPriceDataUpdated ```solidity event SynthPriceDataUpdated(uint256 synthMarketId, bytes32 buyFeedId, bytes32 sellFeedId) @@ -1047,7 +1045,7 @@ Anyone who is willing and able to spend the gas can call this method. * `buyFeedId` (*bytes32*) - the oracle manager feed id for the buy price * `sellFeedId` (*bytes32*) - the oracle manager feed id for the sell price -### DecayRateUpdated +#### DecayRateUpdated ```solidity event DecayRateUpdated(uint128 marketId, uint256 rate) @@ -1059,7 +1057,7 @@ Anyone who is willing and able to spend the gas can call this method. * `marketId` (*uint128*) - Id of the synth market * `rate` (*uint256*) - the new decay rate (1e16 means 1% decay per year) -### MarketOwnerNominated +#### MarketOwnerNominated ```solidity event MarketOwnerNominated(uint128 marketId, address newOwner) @@ -1071,7 +1069,7 @@ Anyone who is willing and able to spend the gas can call this method. * `marketId` (*uint128*) - id of the market * `newOwner` (*address*) - The address that has been nominated. -### MarketNominationRenounced +#### MarketNominationRenounced ```solidity event MarketNominationRenounced(uint128 marketId, address nominee) @@ -1083,7 +1081,7 @@ Anyone who is willing and able to spend the gas can call this method. * `marketId` (*uint128*) - id of the market * `nominee` (*address*) - The address that has been nominated. -### MarketOwnerChanged +#### MarketOwnerChanged ```solidity event MarketOwnerChanged(uint128 marketId, address oldOwner, address newOwner) @@ -1096,9 +1094,9 @@ Anyone who is willing and able to spend the gas can call this method. * `oldOwner` (*address*) - The previous owner of the market. * `newOwner` (*address*) - The new owner of the market. -## Synth Token Module +### Synth Token Module -### setDecayRate +#### setDecayRate ```solidity function setDecayRate(uint256 _rate) external @@ -1109,7 +1107,7 @@ Anyone who is willing and able to spend the gas can call this method. **Parameters** * `_rate` (*uint256*) - The decay rate with 18 decimals (1e16 means 1% decay per year). -### decayRate +#### decayRate ```solidity function decayRate() external returns (uint256) @@ -1117,7 +1115,7 @@ Anyone who is willing and able to spend the gas can call this method. get decay rate for a year -### advanceEpoch +#### advanceEpoch ```solidity function advanceEpoch() external returns (uint256) @@ -1125,7 +1123,7 @@ Anyone who is willing and able to spend the gas can call this method. advance epoch manually in order to avoid precision loss -### isInitialized +#### isInitialized ```solidity function isInitialized() external returns (bool) @@ -1135,7 +1133,7 @@ Anyone who is willing and able to spend the gas can call this method. **Returns** * `[0]` (*bool*) - A boolean with the result of the query. -### initialize +#### initialize ```solidity function initialize(string tokenName, string tokenSymbol, uint8 tokenDecimals) external @@ -1143,7 +1141,7 @@ Anyone who is willing and able to spend the gas can call this method. Initializes the token with name, symbol, and decimals. -### mint +#### mint ```solidity function mint(address to, uint256 amount) external @@ -1155,7 +1153,7 @@ Anyone who is willing and able to spend the gas can call this method. * `to` (*address*) - The address to receive the newly minted tokens. * `amount` (*uint256*) - The amount of tokens to mint. -### burn +#### burn ```solidity function burn(address from, uint256 amount) external @@ -1167,7 +1165,7 @@ Anyone who is willing and able to spend the gas can call this method. * `from` (*address*) - The address whose tokens will be burnt. * `amount` (*uint256*) - The amount of tokens to burn. -### setAllowance +#### setAllowance ```solidity function setAllowance(address from, address spender, uint256 amount) external @@ -1180,7 +1178,7 @@ Anyone who is willing and able to spend the gas can call this method. * `spender` (*address*) - The address that is given allowance. * `amount` (*uint256*) - The amount of allowance being given. -### name +#### name ```solidity function name() external view returns (string) @@ -1190,7 +1188,7 @@ Anyone who is willing and able to spend the gas can call this method. **Returns** * `[0]` (*string*) - A string with the name of the token. -### symbol +#### symbol ```solidity function symbol() external view returns (string) @@ -1200,7 +1198,7 @@ Anyone who is willing and able to spend the gas can call this method. **Returns** * `[0]` (*string*) - A string with the symbol of the token. -### decimals +#### decimals ```solidity function decimals() external view returns (uint8) @@ -1210,7 +1208,7 @@ Anyone who is willing and able to spend the gas can call this method. **Returns** * `[0]` (*uint8*) - The number of decimals. -### totalSupply +#### totalSupply ```solidity function totalSupply() external view returns (uint256) @@ -1220,7 +1218,7 @@ Anyone who is willing and able to spend the gas can call this method. **Returns** * `[0]` (*uint256*) - The total number of tokens. -### balanceOf +#### balanceOf ```solidity function balanceOf(address owner) external view returns (uint256) @@ -1233,7 +1231,7 @@ Anyone who is willing and able to spend the gas can call this method. **Returns** * `[0]` (*uint256*) - The number of tokens owned by the user. -### allowance +#### allowance ```solidity function allowance(address owner, address spender) external view returns (uint256) @@ -1247,7 +1245,7 @@ Anyone who is willing and able to spend the gas can call this method. **Returns** * `[0]` (*uint256*) - The amount of tokens `spender` can transfer on `owner`'s behalf. -### transfer +#### transfer ```solidity function transfer(address to, uint256 amount) external returns (bool) @@ -1261,7 +1259,7 @@ Anyone who is willing and able to spend the gas can call this method. **Returns** * `[0]` (*bool*) - A boolean which is true if the operation succeeded. -### approve +#### approve ```solidity function approve(address spender, uint256 amount) external returns (bool) @@ -1275,7 +1273,7 @@ Anyone who is willing and able to spend the gas can call this method. **Returns** * `[0]` (*bool*) - A boolean which is true if the operation succeeded. -### increaseAllowance +#### increaseAllowance ```solidity function increaseAllowance(address spender, uint256 addedValue) external returns (bool) @@ -1292,7 +1290,7 @@ Requirements: - `spender` cannot be the zero address. -### decreaseAllowance +#### decreaseAllowance ```solidity function decreaseAllowance(address spender, uint256 subtractedValue) external returns (bool) @@ -1311,7 +1309,7 @@ Requirements: - `spender` must have allowance for the caller of at least `subtractedValue`. -### transferFrom +#### transferFrom ```solidity function transferFrom(address from, address to, uint256 amount) external returns (bool) @@ -1327,7 +1325,7 @@ Requirements: **Returns** * `[0]` (*bool*) - A boolean which is true if the operation succeeded. -### Transfer +#### Transfer ```solidity event Transfer(address from, address to, uint256 amount) @@ -1340,7 +1338,7 @@ Requirements: * `to` (*address*) - The address that received the tokens. * `amount` (*uint256*) - The number of tokens that were transferred. -### Approval +#### Approval ```solidity event Approval(address owner, address spender, uint256 amount) @@ -1353,9 +1351,9 @@ Requirements: * `spender` (*address*) - The address that received the allowance. * `amount` (*uint256*) - The number of tokens that were added to `spender`'s allowance. -## Wrapper Module +### Wrapper Module -### setWrapper +#### setWrapper ```solidity function setWrapper(uint128 marketId, address wrapCollateralType, uint256 maxWrappableAmount) external @@ -1371,7 +1369,7 @@ There is a synthetix v3 core system supply cap also set. If the current supply b * `wrapCollateralType` (*address*) - The collateral being used to wrap the synth. * `maxWrappableAmount` (*uint256*) - The maximum amount of collateral that can be wrapped. -### wrap +#### wrap ```solidity function wrap(uint128 marketId, uint256 wrapAmount, uint256 minAmountReceived) external returns (uint256 amountToMint, struct OrderFees.Data fees) @@ -1389,7 +1387,7 @@ There is a synthetix v3 core system supply cap also set. If the current supply b **Returns** * `amountToMint` (*uint256*) - Amount of synth returned to user. * `fees` (*struct OrderFees.Data*) - breakdown of all fees. in this case, only wrapper fees are returned. -### unwrap +#### unwrap ```solidity function unwrap(uint128 marketId, uint256 unwrapAmount, uint256 minAmountReceived) external returns (uint256 returnCollateralAmount, struct OrderFees.Data fees) @@ -1408,7 +1406,7 @@ There is a synthetix v3 core system supply cap also set. If the current supply b * `returnCollateralAmount` (*uint256*) - Amount of collateral returned. * `fees` (*struct OrderFees.Data*) - breakdown of all fees. in this case, only wrapper fees are returned. -### WrapperSet +#### WrapperSet ```solidity event WrapperSet(uint256 synthMarketId, address wrapCollateralType, uint256 maxWrappableAmount) @@ -1421,7 +1419,7 @@ There is a synthetix v3 core system supply cap also set. If the current supply b * `wrapCollateralType` (*address*) - the collateral used to wrap the synth. * `maxWrappableAmount` (*uint256*) - the local supply cap for the wrapper. -### SynthWrapped +#### SynthWrapped ```solidity event SynthWrapped(uint256 synthMarketId, uint256 amountWrapped, struct OrderFees.Data fees, uint256 feesCollected) @@ -1435,7 +1433,7 @@ There is a synthetix v3 core system supply cap also set. If the current supply b * `fees` (*struct OrderFees.Data*) - breakdown of all the fees incurred for the transaction. * `feesCollected` (*uint256*) - fees collected by the configured FeeCollector for the market (rest of the fees are deposited to market manager). -### SynthUnwrapped +#### SynthUnwrapped ```solidity event SynthUnwrapped(uint256 synthMarketId, uint256 amountUnwrapped, struct OrderFees.Data fees, uint256 feesCollected) diff --git a/package.json b/package.json index 3221727d0b..7ee4c9971e 100644 --- a/package.json +++ b/package.json @@ -37,7 +37,8 @@ "publish:dev": "lerna publish --force-publish --canary --dist-tag dev --preid dev.$(git rev-parse --short HEAD)", "publish-contracts": "yarn workspaces foreach --verbose run publish-contracts", "prepublishOnly": "node ./prepublishOnly.js", - "docgen": "yarn workspaces foreach --verbose run docgen", + "docgen": "yarn clean && yarn workspaces foreach --verbose run docgen && yarn docgen:contracts", + "docgen:contracts": "yarn workspace @synthetixio/docgen docgen:contracts", "subgraphgen": "yarn workspaces foreach --verbose run subgraphgen" }, "devDependencies": { diff --git a/protocol/governance/docs/index.md b/protocol/governance/docs/index.md index 2573b37d9a..7538db4083 100644 --- a/protocol/governance/docs/index.md +++ b/protocol/governance/docs/index.md @@ -1,8 +1,6 @@ -# Solidity API +### Council Token Module -## Council Token Module - -### isInitialized +#### isInitialized ```solidity function isInitialized() external returns (bool) @@ -12,7 +10,7 @@ **Returns** * `[0]` (*bool*) - A boolean with the result of the query. -### initialize +#### initialize ```solidity function initialize(string tokenName, string tokenSymbol, string uri) external @@ -20,7 +18,7 @@ Initializes the token with name, symbol, and uri. -### mint +#### mint ```solidity function mint(address to, uint256 tokenId) external @@ -32,7 +30,7 @@ * `to` (*address*) - The address to receive the newly minted tokens. * `tokenId` (*uint256*) - The ID of the newly minted token -### safeMint +#### safeMint ```solidity function safeMint(address to, uint256 tokenId, bytes data) external @@ -45,7 +43,7 @@ * `tokenId` (*uint256*) - The ID of the newly minted token * `data` (*bytes*) - any data which should be sent to the receiver -### burn +#### burn ```solidity function burn(uint256 tokenId) external @@ -56,7 +54,7 @@ **Parameters** * `tokenId` (*uint256*) - The token to burn -### setAllowance +#### setAllowance ```solidity function setAllowance(uint256 tokenId, address spender) external @@ -68,7 +66,7 @@ * `tokenId` (*uint256*) - The token which should be allowed to spender * `spender` (*address*) - The address that is given allowance. -### setBaseTokenURI +#### setBaseTokenURI ```solidity function setBaseTokenURI(string uri) external @@ -79,7 +77,7 @@ **Parameters** * `uri` (*string*) - The new base token uri -### totalSupply +#### totalSupply ```solidity function totalSupply() external view returns (uint256) @@ -87,7 +85,7 @@ Returns the total amount of tokens stored by the contract. -### tokenOfOwnerByIndex +#### tokenOfOwnerByIndex ```solidity function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256) @@ -100,7 +98,7 @@ Requirements: - `owner` must be a valid address - `index` must be less than the balance of the tokens for the owner -### tokenByIndex +#### tokenByIndex ```solidity function tokenByIndex(uint256 index) external view returns (uint256) @@ -112,7 +110,7 @@ Use along with {totalSupply} to enumerate all tokens. Requirements: - `index` must be less than the total supply of the tokens -### balanceOf +#### balanceOf ```solidity function balanceOf(address holder) external view returns (uint256 balance) @@ -124,7 +122,7 @@ Requirements: - `holder` must be a valid address -### ownerOf +#### ownerOf ```solidity function ownerOf(uint256 tokenId) external view returns (address owner) @@ -136,7 +134,7 @@ Requirements: - `tokenId` must exist. -### safeTransferFrom +#### safeTransferFrom ```solidity function safeTransferFrom(address from, address to, uint256 tokenId, bytes data) external @@ -154,7 +152,7 @@ Requirements: Emits a {Transfer} event. -### safeTransferFrom +#### safeTransferFrom ```solidity function safeTransferFrom(address from, address to, uint256 tokenId) external @@ -173,7 +171,7 @@ Requirements: Emits a {Transfer} event. -### transferFrom +#### transferFrom ```solidity function transferFrom(address from, address to, uint256 tokenId) external @@ -192,7 +190,7 @@ Requirements: Emits a {Transfer} event. -### approve +#### approve ```solidity function approve(address to, uint256 tokenId) external @@ -210,7 +208,7 @@ Requirements: Emits an {Approval} event. -### setApprovalForAll +#### setApprovalForAll ```solidity function setApprovalForAll(address operator, bool approved) external @@ -225,7 +223,7 @@ Requirements: Emits an {ApprovalForAll} event. -### getApproved +#### getApproved ```solidity function getApproved(uint256 tokenId) external view returns (address operator) @@ -237,7 +235,7 @@ Requirements: - `tokenId` must exist. -### isApprovedForAll +#### isApprovedForAll ```solidity function isApprovedForAll(address owner, address operator) external view returns (bool) @@ -247,7 +245,7 @@ Requirements: See {setApprovalForAll} -### Transfer +#### Transfer ```solidity event Transfer(address from, address to, uint256 tokenId) @@ -255,7 +253,7 @@ See {setApprovalForAll} Emitted when `tokenId` token is transferred from `from` to `to`. -### Approval +#### Approval ```solidity event Approval(address owner, address approved, uint256 tokenId) @@ -263,7 +261,7 @@ See {setApprovalForAll} Emitted when `owner` enables `approved` to manage the `tokenId` token. -### ApprovalForAll +#### ApprovalForAll ```solidity event ApprovalForAll(address owner, address operator, bool approved) @@ -271,17 +269,17 @@ See {setApprovalForAll} Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets. -## IDebtShare +### IDebtShare -### balanceOfOnPeriod +#### balanceOfOnPeriod ```solidity function balanceOfOnPeriod(address account, uint256 periodId) external view returns (uint256) ``` -## Election Inspector Module +### Election Inspector Module -### getEpochStartDateForIndex +#### getEpochStartDateForIndex ```solidity function getEpochStartDateForIndex(uint256 epochIndex) external view returns (uint64) @@ -289,7 +287,7 @@ See {setApprovalForAll} Returns the date in which the given epoch started -### getEpochEndDateForIndex +#### getEpochEndDateForIndex ```solidity function getEpochEndDateForIndex(uint256 epochIndex) external view returns (uint64) @@ -297,7 +295,7 @@ See {setApprovalForAll} Returns the date in which the given epoch ended -### getNominationPeriodStartDateForIndex +#### getNominationPeriodStartDateForIndex ```solidity function getNominationPeriodStartDateForIndex(uint256 epochIndex) external view returns (uint64) @@ -305,7 +303,7 @@ See {setApprovalForAll} Returns the date in which the Nomination period in the given epoch started -### getVotingPeriodStartDateForIndex +#### getVotingPeriodStartDateForIndex ```solidity function getVotingPeriodStartDateForIndex(uint256 epochIndex) external view returns (uint64) @@ -313,7 +311,7 @@ See {setApprovalForAll} Returns the date in which the Voting period in the given epoch started -### wasNominated +#### wasNominated ```solidity function wasNominated(address candidate, uint256 epochIndex) external view returns (bool) @@ -321,7 +319,7 @@ See {setApprovalForAll} Shows if a candidate was nominated in the given epoch -### getNomineesAtEpoch +#### getNomineesAtEpoch ```solidity function getNomineesAtEpoch(uint256 epochIndex) external view returns (address[]) @@ -329,7 +327,7 @@ See {setApprovalForAll} Returns a list of all nominated candidates in the given epoch -### getBallotVotedAtEpoch +#### getBallotVotedAtEpoch ```solidity function getBallotVotedAtEpoch(address user, uint256 epochIndex) external view returns (bytes32) @@ -337,7 +335,7 @@ See {setApprovalForAll} Returns the ballot id that user voted on in the given election -### hasVotedInEpoch +#### hasVotedInEpoch ```solidity function hasVotedInEpoch(address user, uint256 epochIndex) external view returns (bool) @@ -345,7 +343,7 @@ See {setApprovalForAll} Returns if user has voted in the given election -### getBallotVotesInEpoch +#### getBallotVotesInEpoch ```solidity function getBallotVotesInEpoch(bytes32 ballotId, uint256 epochIndex) external view returns (uint256) @@ -353,7 +351,7 @@ See {setApprovalForAll} Returns the number of votes given to a particular ballot in a given epoch -### getBallotCandidatesInEpoch +#### getBallotCandidatesInEpoch ```solidity function getBallotCandidatesInEpoch(bytes32 ballotId, uint256 epochIndex) external view returns (address[]) @@ -361,7 +359,7 @@ See {setApprovalForAll} Returns the list of candidates that a particular ballot has in a given epoch -### getCandidateVotesInEpoch +#### getCandidateVotesInEpoch ```solidity function getCandidateVotesInEpoch(address candidate, uint256 epochIndex) external view returns (uint256) @@ -369,7 +367,7 @@ See {setApprovalForAll} Returns the number of votes a candidate received in a given epoch -### getElectionWinnersInEpoch +#### getElectionWinnersInEpoch ```solidity function getElectionWinnersInEpoch(uint256 epochIndex) external view returns (address[]) @@ -377,9 +375,9 @@ See {setApprovalForAll} Returns the winners of the given election -## Election Module +### Election Module -### initOrUpgradeElectionModule +#### initOrUpgradeElectionModule ```solidity function initOrUpgradeElectionModule(address[] firstCouncil, uint8 minimumActiveMembers, uint64 nominationPeriodStartDate, uint64 votingPeriodStartDate, uint64 epochEndDate) external @@ -387,7 +385,7 @@ See {setApprovalForAll} Initializes the module and immediately starts the first epoch -### isElectionModuleInitialized +#### isElectionModuleInitialized ```solidity function isElectionModuleInitialized() external view returns (bool) @@ -395,7 +393,7 @@ See {setApprovalForAll} Shows whether the module has been initialized -### tweakEpochSchedule +#### tweakEpochSchedule ```solidity function tweakEpochSchedule(uint64 newNominationPeriodStartDate, uint64 newVotingPeriodStartDate, uint64 newEpochEndDate) external @@ -403,7 +401,7 @@ See {setApprovalForAll} Adjusts the current epoch schedule requiring that the current period remains Administration, and that changes are small (see setMaxDateAdjustmentTolerance) -### modifyEpochSchedule +#### modifyEpochSchedule ```solidity function modifyEpochSchedule(uint64 newNominationPeriodStartDate, uint64 newVotingPeriodStartDate, uint64 newEpochEndDate) external @@ -411,7 +409,7 @@ See {setApprovalForAll} Adjusts the current epoch schedule requiring that the current period remains Administration -### setMinEpochDurations +#### setMinEpochDurations ```solidity function setMinEpochDurations(uint64 newMinNominationPeriodDuration, uint64 newMinVotingPeriodDuration, uint64 newMinEpochDuration) external @@ -419,7 +417,7 @@ See {setApprovalForAll} Determines minimum values for epoch schedule adjustments -### setMaxDateAdjustmentTolerance +#### setMaxDateAdjustmentTolerance ```solidity function setMaxDateAdjustmentTolerance(uint64 newMaxDateAdjustmentTolerance) external @@ -427,7 +425,7 @@ See {setApprovalForAll} Determines adjustment size for tweakEpochSchedule -### setDefaultBallotEvaluationBatchSize +#### setDefaultBallotEvaluationBatchSize ```solidity function setDefaultBallotEvaluationBatchSize(uint256 newDefaultBallotEvaluationBatchSize) external @@ -435,7 +433,7 @@ See {setApprovalForAll} Determines batch size when evaluate() is called with numBallots = 0 -### setNextEpochSeatCount +#### setNextEpochSeatCount ```solidity function setNextEpochSeatCount(uint8 newSeatCount) external @@ -443,7 +441,7 @@ See {setApprovalForAll} Determines the number of council members in the next epoch -### setMinimumActiveMembers +#### setMinimumActiveMembers ```solidity function setMinimumActiveMembers(uint8 newMinimumActiveMembers) external @@ -451,7 +449,7 @@ See {setApprovalForAll} Determines the minimum number of council members before triggering an emergency election -### dismissMembers +#### dismissMembers ```solidity function dismissMembers(address[] members) external @@ -459,7 +457,7 @@ See {setApprovalForAll} Allows the owner to remove one or more council members, triggering an election if a threshold is met -### nominate +#### nominate ```solidity function nominate() external @@ -467,7 +465,7 @@ See {setApprovalForAll} Allows anyone to self-nominate during the Nomination period -### withdrawNomination +#### withdrawNomination ```solidity function withdrawNomination() external @@ -475,7 +473,7 @@ See {setApprovalForAll} Self-withdrawal of nominations during the Nomination period -### cast +#### cast ```solidity function cast(address[] candidates) external @@ -483,7 +481,7 @@ See {setApprovalForAll} Allows anyone with vote power to vote on nominated candidates during the Voting period -### withdrawVote +#### withdrawVote ```solidity function withdrawVote() external @@ -491,7 +489,7 @@ See {setApprovalForAll} Allows votes to be withdraw -### evaluate +#### evaluate ```solidity function evaluate(uint256 numBallots) external @@ -499,7 +497,7 @@ See {setApprovalForAll} Processes ballots in batches during the Evaluation period (after epochEndDate) -### resolve +#### resolve ```solidity function resolve() external @@ -507,7 +505,7 @@ See {setApprovalForAll} Shuffles NFTs and resolves an election after it has been evaluated -### getMinEpochDurations +#### getMinEpochDurations ```solidity function getMinEpochDurations() external view returns (uint64 minNominationPeriodDuration, uint64 minVotingPeriodDuration, uint64 minEpochDuration) @@ -515,7 +513,7 @@ See {setApprovalForAll} Exposes minimum durations required when adjusting epoch schedules -### getMaxDateAdjustmenTolerance +#### getMaxDateAdjustmenTolerance ```solidity function getMaxDateAdjustmenTolerance() external view returns (uint64) @@ -523,7 +521,7 @@ See {setApprovalForAll} Exposes maximum size of adjustments when calling tweakEpochSchedule -### getDefaultBallotEvaluationBatchSize +#### getDefaultBallotEvaluationBatchSize ```solidity function getDefaultBallotEvaluationBatchSize() external view returns (uint256) @@ -531,7 +529,7 @@ See {setApprovalForAll} Shows the default batch size when calling evaluate() with numBallots = 0 -### getNextEpochSeatCount +#### getNextEpochSeatCount ```solidity function getNextEpochSeatCount() external view returns (uint8) @@ -539,7 +537,7 @@ See {setApprovalForAll} Shows the number of council members that the next epoch will have -### getMinimumActiveMembers +#### getMinimumActiveMembers ```solidity function getMinimumActiveMembers() external view returns (uint8) @@ -547,7 +545,7 @@ See {setApprovalForAll} Returns the minimum active members that the council needs to avoid an emergency election -### getEpochIndex +#### getEpochIndex ```solidity function getEpochIndex() external view returns (uint256) @@ -555,7 +553,7 @@ See {setApprovalForAll} Returns the index of the current epoch. The first epoch's index is 1 -### getEpochStartDate +#### getEpochStartDate ```solidity function getEpochStartDate() external view returns (uint64) @@ -563,7 +561,7 @@ See {setApprovalForAll} Returns the date in which the current epoch started -### getEpochEndDate +#### getEpochEndDate ```solidity function getEpochEndDate() external view returns (uint64) @@ -571,7 +569,7 @@ See {setApprovalForAll} Returns the date in which the current epoch will end -### getNominationPeriodStartDate +#### getNominationPeriodStartDate ```solidity function getNominationPeriodStartDate() external view returns (uint64) @@ -579,7 +577,7 @@ See {setApprovalForAll} Returns the date in which the Nomination period in the current epoch will start -### getVotingPeriodStartDate +#### getVotingPeriodStartDate ```solidity function getVotingPeriodStartDate() external view returns (uint64) @@ -587,7 +585,7 @@ See {setApprovalForAll} Returns the date in which the Voting period in the current epoch will start -### getCurrentPeriod +#### getCurrentPeriod ```solidity function getCurrentPeriod() external view returns (uint256) @@ -595,7 +593,7 @@ See {setApprovalForAll} Returns the current period type: Administration, Nomination, Voting, Evaluation -### isNominated +#### isNominated ```solidity function isNominated(address candidate) external view returns (bool) @@ -603,7 +601,7 @@ See {setApprovalForAll} Shows if a candidate has been nominated in the current epoch -### getNominees +#### getNominees ```solidity function getNominees() external view returns (address[]) @@ -611,7 +609,7 @@ See {setApprovalForAll} Returns a list of all nominated candidates in the current epoch -### calculateBallotId +#### calculateBallotId ```solidity function calculateBallotId(address[] candidates) external pure returns (bytes32) @@ -619,7 +617,7 @@ See {setApprovalForAll} Hashes a list of candidates (used for identifying and storing ballots) -### getBallotVoted +#### getBallotVoted ```solidity function getBallotVoted(address user) external view returns (bytes32) @@ -627,7 +625,7 @@ See {setApprovalForAll} Returns the ballot id that user voted on in the current election -### hasVoted +#### hasVoted ```solidity function hasVoted(address user) external view returns (bool) @@ -635,7 +633,7 @@ See {setApprovalForAll} Returns if user has voted in the current election -### getVotePower +#### getVotePower ```solidity function getVotePower(address user) external view returns (uint256) @@ -643,7 +641,7 @@ See {setApprovalForAll} Returns the vote power of user in the current election -### getBallotVotes +#### getBallotVotes ```solidity function getBallotVotes(bytes32 ballotId) external view returns (uint256) @@ -651,7 +649,7 @@ See {setApprovalForAll} Returns the number of votes given to a particular ballot -### getBallotCandidates +#### getBallotCandidates ```solidity function getBallotCandidates(bytes32 ballotId) external view returns (address[]) @@ -659,7 +657,7 @@ See {setApprovalForAll} Returns the list of candidates that a particular ballot has -### isElectionEvaluated +#### isElectionEvaluated ```solidity function isElectionEvaluated() external view returns (bool) @@ -667,7 +665,7 @@ See {setApprovalForAll} Returns whether all ballots in the current election have been counted -### getCandidateVotes +#### getCandidateVotes ```solidity function getCandidateVotes(address candidate) external view returns (uint256) @@ -675,7 +673,7 @@ See {setApprovalForAll} Returns the number of votes a candidate received. Requires the election to be partially or totally evaluated -### getElectionWinners +#### getElectionWinners ```solidity function getElectionWinners() external view returns (address[]) @@ -683,7 +681,7 @@ See {setApprovalForAll} Returns the winners of the current election. Requires the election to be partially or totally evaluated -### getCouncilToken +#### getCouncilToken ```solidity function getCouncilToken() external view returns (address) @@ -691,7 +689,7 @@ See {setApprovalForAll} Returns the address of the council NFT token -### getCouncilMembers +#### getCouncilMembers ```solidity function getCouncilMembers() external view returns (address[]) @@ -699,9 +697,9 @@ See {setApprovalForAll} Returns the current NFT token holders -## Synthetix Election Module +### Synthetix Election Module -### initOrUpgradeElectionModule +#### initOrUpgradeElectionModule ```solidity function initOrUpgradeElectionModule(address[] firstCouncil, uint8 minimumActiveMembers, uint64 nominationPeriodStartDate, uint64 votingPeriodStartDate, uint64 epochEndDate, address debtShareContract) external @@ -709,7 +707,7 @@ See {setApprovalForAll} Initializes the module and immediately starts the first epoch -### setDebtShareContract +#### setDebtShareContract ```solidity function setDebtShareContract(address newDebtShareContractAddress) external @@ -717,7 +715,7 @@ See {setApprovalForAll} Sets the Synthetix v2 DebtShare contract that determines vote power -### getDebtShareContract +#### getDebtShareContract ```solidity function getDebtShareContract() external view returns (address) @@ -725,7 +723,7 @@ See {setApprovalForAll} Returns the Synthetix v2 DebtShare contract that determines vote power -### setDebtShareSnapshotId +#### setDebtShareSnapshotId ```solidity function setDebtShareSnapshotId(uint256 snapshotId) external @@ -733,7 +731,7 @@ See {setApprovalForAll} Sets the Synthetix v2 DebtShare snapshot that determines vote power for this epoch -### getDebtShareSnapshotId +#### getDebtShareSnapshotId ```solidity function getDebtShareSnapshotId() external view returns (uint256) @@ -741,7 +739,7 @@ See {setApprovalForAll} Returns the Synthetix v2 DebtShare snapshot id set for this epoch -### getDebtShare +#### getDebtShare ```solidity function getDebtShare(address user) external view returns (uint256) @@ -749,7 +747,7 @@ See {setApprovalForAll} Returns the Synthetix v2 debt share for the provided address, at this epoch's snapshot -### setCrossChainDebtShareMerkleRoot +#### setCrossChainDebtShareMerkleRoot ```solidity function setCrossChainDebtShareMerkleRoot(bytes32 merkleRoot, uint256 blocknumber) external @@ -757,7 +755,7 @@ See {setApprovalForAll} Allows the system owner to declare a merkle root for user debt shares on other chains for this epoch -### getCrossChainDebtShareMerkleRoot +#### getCrossChainDebtShareMerkleRoot ```solidity function getCrossChainDebtShareMerkleRoot() external view returns (bytes32) @@ -765,7 +763,7 @@ See {setApprovalForAll} Returns the current epoch's merkle root for user debt shares on other chains -### getCrossChainDebtShareMerkleRootBlockNumber +#### getCrossChainDebtShareMerkleRootBlockNumber ```solidity function getCrossChainDebtShareMerkleRootBlockNumber() external view returns (uint256) @@ -773,7 +771,7 @@ See {setApprovalForAll} Returns the current epoch's merkle root block number -### declareCrossChainDebtShare +#### declareCrossChainDebtShare ```solidity function declareCrossChainDebtShare(address account, uint256 debtShare, bytes32[] merkleProof) external @@ -781,7 +779,7 @@ See {setApprovalForAll} Allows users to declare their Synthetix v2 debt shares on other chains -### getDeclaredCrossChainDebtShare +#### getDeclaredCrossChainDebtShare ```solidity function getDeclaredCrossChainDebtShare(address account) external view returns (uint256) @@ -789,7 +787,7 @@ See {setApprovalForAll} Returns the Synthetix v2 debt shares for the provided address, at this epoch's snapshot, in other chains -### declareAndCast +#### declareAndCast ```solidity function declareAndCast(uint256 debtShare, bytes32[] merkleProof, address[] candidates) external @@ -797,7 +795,7 @@ See {setApprovalForAll} Declares cross chain debt shares and casts a vote -### initOrUpgradeElectionModule +#### initOrUpgradeElectionModule ```solidity function initOrUpgradeElectionModule(address[] firstCouncil, uint8 minimumActiveMembers, uint64 nominationPeriodStartDate, uint64 votingPeriodStartDate, uint64 epochEndDate) external @@ -805,7 +803,7 @@ See {setApprovalForAll} Initializes the module and immediately starts the first epoch -### isElectionModuleInitialized +#### isElectionModuleInitialized ```solidity function isElectionModuleInitialized() external view returns (bool) @@ -813,7 +811,7 @@ See {setApprovalForAll} Shows whether the module has been initialized -### tweakEpochSchedule +#### tweakEpochSchedule ```solidity function tweakEpochSchedule(uint64 newNominationPeriodStartDate, uint64 newVotingPeriodStartDate, uint64 newEpochEndDate) external @@ -821,7 +819,7 @@ See {setApprovalForAll} Adjusts the current epoch schedule requiring that the current period remains Administration, and that changes are small (see setMaxDateAdjustmentTolerance) -### modifyEpochSchedule +#### modifyEpochSchedule ```solidity function modifyEpochSchedule(uint64 newNominationPeriodStartDate, uint64 newVotingPeriodStartDate, uint64 newEpochEndDate) external @@ -829,7 +827,7 @@ See {setApprovalForAll} Adjusts the current epoch schedule requiring that the current period remains Administration -### setMinEpochDurations +#### setMinEpochDurations ```solidity function setMinEpochDurations(uint64 newMinNominationPeriodDuration, uint64 newMinVotingPeriodDuration, uint64 newMinEpochDuration) external @@ -837,7 +835,7 @@ See {setApprovalForAll} Determines minimum values for epoch schedule adjustments -### setMaxDateAdjustmentTolerance +#### setMaxDateAdjustmentTolerance ```solidity function setMaxDateAdjustmentTolerance(uint64 newMaxDateAdjustmentTolerance) external @@ -845,7 +843,7 @@ See {setApprovalForAll} Determines adjustment size for tweakEpochSchedule -### setDefaultBallotEvaluationBatchSize +#### setDefaultBallotEvaluationBatchSize ```solidity function setDefaultBallotEvaluationBatchSize(uint256 newDefaultBallotEvaluationBatchSize) external @@ -853,7 +851,7 @@ See {setApprovalForAll} Determines batch size when evaluate() is called with numBallots = 0 -### setNextEpochSeatCount +#### setNextEpochSeatCount ```solidity function setNextEpochSeatCount(uint8 newSeatCount) external @@ -861,7 +859,7 @@ See {setApprovalForAll} Determines the number of council members in the next epoch -### setMinimumActiveMembers +#### setMinimumActiveMembers ```solidity function setMinimumActiveMembers(uint8 newMinimumActiveMembers) external @@ -869,7 +867,7 @@ See {setApprovalForAll} Determines the minimum number of council members before triggering an emergency election -### dismissMembers +#### dismissMembers ```solidity function dismissMembers(address[] members) external @@ -877,7 +875,7 @@ See {setApprovalForAll} Allows the owner to remove one or more council members, triggering an election if a threshold is met -### nominate +#### nominate ```solidity function nominate() external @@ -885,7 +883,7 @@ See {setApprovalForAll} Allows anyone to self-nominate during the Nomination period -### withdrawNomination +#### withdrawNomination ```solidity function withdrawNomination() external @@ -893,7 +891,7 @@ See {setApprovalForAll} Self-withdrawal of nominations during the Nomination period -### cast +#### cast ```solidity function cast(address[] candidates) external @@ -901,7 +899,7 @@ See {setApprovalForAll} Allows anyone with vote power to vote on nominated candidates during the Voting period -### withdrawVote +#### withdrawVote ```solidity function withdrawVote() external @@ -909,7 +907,7 @@ See {setApprovalForAll} Allows votes to be withdraw -### evaluate +#### evaluate ```solidity function evaluate(uint256 numBallots) external @@ -917,7 +915,7 @@ See {setApprovalForAll} Processes ballots in batches during the Evaluation period (after epochEndDate) -### resolve +#### resolve ```solidity function resolve() external @@ -925,7 +923,7 @@ See {setApprovalForAll} Shuffles NFTs and resolves an election after it has been evaluated -### getMinEpochDurations +#### getMinEpochDurations ```solidity function getMinEpochDurations() external view returns (uint64 minNominationPeriodDuration, uint64 minVotingPeriodDuration, uint64 minEpochDuration) @@ -933,7 +931,7 @@ See {setApprovalForAll} Exposes minimum durations required when adjusting epoch schedules -### getMaxDateAdjustmenTolerance +#### getMaxDateAdjustmenTolerance ```solidity function getMaxDateAdjustmenTolerance() external view returns (uint64) @@ -941,7 +939,7 @@ See {setApprovalForAll} Exposes maximum size of adjustments when calling tweakEpochSchedule -### getDefaultBallotEvaluationBatchSize +#### getDefaultBallotEvaluationBatchSize ```solidity function getDefaultBallotEvaluationBatchSize() external view returns (uint256) @@ -949,7 +947,7 @@ See {setApprovalForAll} Shows the default batch size when calling evaluate() with numBallots = 0 -### getNextEpochSeatCount +#### getNextEpochSeatCount ```solidity function getNextEpochSeatCount() external view returns (uint8) @@ -957,7 +955,7 @@ See {setApprovalForAll} Shows the number of council members that the next epoch will have -### getMinimumActiveMembers +#### getMinimumActiveMembers ```solidity function getMinimumActiveMembers() external view returns (uint8) @@ -965,7 +963,7 @@ See {setApprovalForAll} Returns the minimum active members that the council needs to avoid an emergency election -### getEpochIndex +#### getEpochIndex ```solidity function getEpochIndex() external view returns (uint256) @@ -973,7 +971,7 @@ See {setApprovalForAll} Returns the index of the current epoch. The first epoch's index is 1 -### getEpochStartDate +#### getEpochStartDate ```solidity function getEpochStartDate() external view returns (uint64) @@ -981,7 +979,7 @@ See {setApprovalForAll} Returns the date in which the current epoch started -### getEpochEndDate +#### getEpochEndDate ```solidity function getEpochEndDate() external view returns (uint64) @@ -989,7 +987,7 @@ See {setApprovalForAll} Returns the date in which the current epoch will end -### getNominationPeriodStartDate +#### getNominationPeriodStartDate ```solidity function getNominationPeriodStartDate() external view returns (uint64) @@ -997,7 +995,7 @@ See {setApprovalForAll} Returns the date in which the Nomination period in the current epoch will start -### getVotingPeriodStartDate +#### getVotingPeriodStartDate ```solidity function getVotingPeriodStartDate() external view returns (uint64) @@ -1005,7 +1003,7 @@ See {setApprovalForAll} Returns the date in which the Voting period in the current epoch will start -### getCurrentPeriod +#### getCurrentPeriod ```solidity function getCurrentPeriod() external view returns (uint256) @@ -1013,7 +1011,7 @@ See {setApprovalForAll} Returns the current period type: Administration, Nomination, Voting, Evaluation -### isNominated +#### isNominated ```solidity function isNominated(address candidate) external view returns (bool) @@ -1021,7 +1019,7 @@ See {setApprovalForAll} Shows if a candidate has been nominated in the current epoch -### getNominees +#### getNominees ```solidity function getNominees() external view returns (address[]) @@ -1029,7 +1027,7 @@ See {setApprovalForAll} Returns a list of all nominated candidates in the current epoch -### calculateBallotId +#### calculateBallotId ```solidity function calculateBallotId(address[] candidates) external pure returns (bytes32) @@ -1037,7 +1035,7 @@ See {setApprovalForAll} Hashes a list of candidates (used for identifying and storing ballots) -### getBallotVoted +#### getBallotVoted ```solidity function getBallotVoted(address user) external view returns (bytes32) @@ -1045,7 +1043,7 @@ See {setApprovalForAll} Returns the ballot id that user voted on in the current election -### hasVoted +#### hasVoted ```solidity function hasVoted(address user) external view returns (bool) @@ -1053,7 +1051,7 @@ See {setApprovalForAll} Returns if user has voted in the current election -### getVotePower +#### getVotePower ```solidity function getVotePower(address user) external view returns (uint256) @@ -1061,7 +1059,7 @@ See {setApprovalForAll} Returns the vote power of user in the current election -### getBallotVotes +#### getBallotVotes ```solidity function getBallotVotes(bytes32 ballotId) external view returns (uint256) @@ -1069,7 +1067,7 @@ See {setApprovalForAll} Returns the number of votes given to a particular ballot -### getBallotCandidates +#### getBallotCandidates ```solidity function getBallotCandidates(bytes32 ballotId) external view returns (address[]) @@ -1077,7 +1075,7 @@ See {setApprovalForAll} Returns the list of candidates that a particular ballot has -### isElectionEvaluated +#### isElectionEvaluated ```solidity function isElectionEvaluated() external view returns (bool) @@ -1085,7 +1083,7 @@ See {setApprovalForAll} Returns whether all ballots in the current election have been counted -### getCandidateVotes +#### getCandidateVotes ```solidity function getCandidateVotes(address candidate) external view returns (uint256) @@ -1093,7 +1091,7 @@ See {setApprovalForAll} Returns the number of votes a candidate received. Requires the election to be partially or totally evaluated -### getElectionWinners +#### getElectionWinners ```solidity function getElectionWinners() external view returns (address[]) @@ -1101,7 +1099,7 @@ See {setApprovalForAll} Returns the winners of the current election. Requires the election to be partially or totally evaluated -### getCouncilToken +#### getCouncilToken ```solidity function getCouncilToken() external view returns (address) @@ -1109,7 +1107,7 @@ See {setApprovalForAll} Returns the address of the council NFT token -### getCouncilMembers +#### getCouncilMembers ```solidity function getCouncilMembers() external view returns (address[]) diff --git a/protocol/oracle-manager/docs/index.md b/protocol/oracle-manager/docs/index.md index 42c99c2dbf..e92f5fcecb 100644 --- a/protocol/oracle-manager/docs/index.md +++ b/protocol/oracle-manager/docs/index.md @@ -1,8 +1,6 @@ -# Solidity API +### Node Module -## Node Module - -### registerNode +#### registerNode ```solidity function registerNode(enum NodeDefinition.NodeType nodeType, bytes parameters, bytes32[] parents) external returns (bytes32 nodeId) @@ -17,7 +15,7 @@ **Returns** * `nodeId` (*bytes32*) - The id of the registered node. -### getNodeId +#### getNodeId ```solidity function getNodeId(enum NodeDefinition.NodeType nodeType, bytes parameters, bytes32[] parents) external returns (bytes32 nodeId) @@ -32,7 +30,7 @@ **Returns** * `nodeId` (*bytes32*) - The id of the node. -### getNode +#### getNode ```solidity function getNode(bytes32 nodeId) external pure returns (struct NodeDefinition.Data node) @@ -45,7 +43,7 @@ **Returns** * `node` (*struct NodeDefinition.Data*) - The node's definition data -### process +#### process ```solidity function process(bytes32 nodeId) external view returns (struct NodeOutput.Data node) @@ -59,7 +57,7 @@ **Returns** * `node` (*struct NodeOutput.Data*) - The node's output data -### NodeRegistered +#### NodeRegistered ```solidity event NodeRegistered(bytes32 nodeId, enum NodeDefinition.NodeType nodeType, bytes parameters, bytes32[] parents) @@ -73,201 +71,181 @@ * `parameters` (*bytes*) - The parameters assigned to this node. * `parents` (*bytes32[]*) - The parents assigned to this node. -## ChainlinkNode +### ChainlinkNode -### process +#### process ```solidity function process(bytes parameters) internal view returns (struct NodeOutput.Data nodeOutput) ``` -### getTwapPrice +#### getTwapPrice ```solidity function getTwapPrice(contract IAggregatorV3Interface chainlink, uint80 latestRoundId, int256 latestPrice, uint256 twapTimeInterval) internal view returns (int256 price) ``` -### isValid +#### isValid ```solidity function isValid(struct NodeDefinition.Data nodeDefinition) internal view returns (bool valid) ``` -## ConstantNode +### ConstantNode -### process +#### process ```solidity function process(bytes parameters) internal view returns (struct NodeOutput.Data nodeOutput) ``` -### isValid +#### isValid ```solidity function isValid(struct NodeDefinition.Data nodeDefinition) internal pure returns (bool valid) ``` -## ExternalNode +### ExternalNode -### process +#### process ```solidity function process(struct NodeOutput.Data[] prices, bytes parameters) internal view returns (struct NodeOutput.Data nodeOutput) ``` -### isValid +#### isValid ```solidity function isValid(struct NodeDefinition.Data nodeDefinition) internal returns (bool valid) ``` -## PriceDeviationCircuitBreakerNode +### PriceDeviationCircuitBreakerNode -### process +#### process ```solidity function process(struct NodeOutput.Data[] parentNodeOutputs, bytes parameters) internal pure returns (struct NodeOutput.Data nodeOutput) ``` -### abs +#### abs ```solidity function abs(int256 x) private pure returns (int256 result) ``` -### isValid +#### isValid ```solidity function isValid(struct NodeDefinition.Data nodeDefinition) internal pure returns (bool valid) ``` -## PythNode +### PythNode -### process +#### process ```solidity function process(bytes parameters) internal view returns (struct NodeOutput.Data nodeOutput) ``` -### isValid +#### isValid ```solidity function isValid(struct NodeDefinition.Data nodeDefinition) internal view returns (bool valid) ``` -## ReducerNode +### ReducerNode -### process +#### process ```solidity function process(struct NodeOutput.Data[] parentNodeOutputs, bytes parameters) internal pure returns (struct NodeOutput.Data nodeOutput) ``` -### median +#### median ```solidity function median(struct NodeOutput.Data[] parentNodeOutputs) internal pure returns (struct NodeOutput.Data medianPrice) ``` -### mean +#### mean ```solidity function mean(struct NodeOutput.Data[] parentNodeOutputs) internal pure returns (struct NodeOutput.Data meanPrice) ``` -### recent +#### recent ```solidity function recent(struct NodeOutput.Data[] parentNodeOutputs) internal pure returns (struct NodeOutput.Data recentPrice) ``` -### max +#### max ```solidity function max(struct NodeOutput.Data[] parentNodeOutputs) internal pure returns (struct NodeOutput.Data maxPrice) ``` -### min +#### min ```solidity function min(struct NodeOutput.Data[] parentNodeOutputs) internal pure returns (struct NodeOutput.Data minPrice) ``` -### mul +#### mul ```solidity function mul(struct NodeOutput.Data[] parentNodeOutputs) internal pure returns (struct NodeOutput.Data mulPrice) ``` -### div +#### div ```solidity function div(struct NodeOutput.Data[] parentNodeOutputs) internal pure returns (struct NodeOutput.Data divPrice) ``` -### quickSort +#### quickSort ```solidity function quickSort(struct NodeOutput.Data[] arr, int256 left, int256 right) internal pure ``` -### isValid +#### isValid ```solidity function isValid(struct NodeDefinition.Data nodeDefinition) internal pure returns (bool valid) ``` -## StalenessCircuitBreakerNode +### StalenessCircuitBreakerNode -### process +#### process ```solidity function process(struct NodeOutput.Data[] parentNodeOutputs, bytes parameters) internal view returns (struct NodeOutput.Data nodeOutput) ``` -### isValid +#### isValid ```solidity function isValid(struct NodeDefinition.Data nodeDefinition) internal pure returns (bool valid) ``` -## UniswapNode +### UniswapNode -### process +#### process ```solidity function process(bytes parameters) internal view returns (struct NodeOutput.Data nodeOutput) ``` -### getQuoteAtTick +#### getQuoteAtTick ```solidity function getQuoteAtTick(int24 tick, uint256 baseAmount, address baseToken, address quoteToken) internal pure returns (uint256 quoteAmount) ``` -### isValid +#### isValid ```solidity function isValid(struct NodeDefinition.Data nodeDefinition) internal view returns (bool valid) ``` -## Router - -### fallback - - ```solidity - fallback() external payable - ``` - -### receive - - ```solidity - receive() external payable - ``` - -### _forward - - ```solidity - function _forward() internal - ``` - diff --git a/protocol/synthetix/docs/index.md b/protocol/synthetix/docs/index.md index 01de50571a..a186ef418a 100644 --- a/protocol/synthetix/docs/index.md +++ b/protocol/synthetix/docs/index.md @@ -1,8 +1,6 @@ -# Solidity API +### Account Module -## Account Module - -### getAccountPermissions +#### getAccountPermissions ```solidity function getAccountPermissions(uint128 accountId) external view returns (struct IAccountModule.AccountPermissions[] accountPerms) @@ -15,7 +13,7 @@ **Returns** * `accountPerms` (*struct IAccountModule.AccountPermissions[]*) - An array of AccountPermission objects describing the permissions granted to the account. -### createAccount +#### createAccount ```solidity function createAccount(uint128 requestedAccountId) external @@ -26,7 +24,7 @@ **Parameters** * `requestedAccountId` (*uint128*) - The id requested for the account being created. Reverts if id already exists. Requirements: - `requestedAccountId` must not already be minted. - `requestedAccountId` must be less than type(uint128).max / 2 Emits a {AccountCreated} event. -### createAccount +#### createAccount ```solidity function createAccount() external returns (uint128 accountId) @@ -36,7 +34,7 @@ Emits a {AccountCreated} event. -### notifyAccountTransfer +#### notifyAccountTransfer ```solidity function notifyAccountTransfer(address to, uint128 accountId) external @@ -50,7 +48,7 @@ Emits a {AccountCreated} event. * `to` (*address*) - The new holder of the account NFT. * `accountId` (*uint128*) - The id of the account that was just transferred. Requirements: - `msg.sender` must be the account token. -### grantPermission +#### grantPermission ```solidity function grantPermission(uint128 accountId, bytes32 permission, address user) external @@ -63,7 +61,7 @@ Emits a {AccountCreated} event. * `permission` (*bytes32*) - The bytes32 identifier of the permission. * `user` (*address*) - The target address that received the permission. Requirements: - `msg.sender` must own the account token with ID `accountId` or have the "admin" permission. Emits a {PermissionGranted} event. -### revokePermission +#### revokePermission ```solidity function revokePermission(uint128 accountId, bytes32 permission, address user) external @@ -76,7 +74,7 @@ Emits a {AccountCreated} event. * `permission` (*bytes32*) - The bytes32 identifier of the permission. * `user` (*address*) - The target address that no longer has the permission. Requirements: - `msg.sender` must own the account token with ID `accountId` or have the "admin" permission. Emits a {PermissionRevoked} event. -### renouncePermission +#### renouncePermission ```solidity function renouncePermission(uint128 accountId, bytes32 permission) external @@ -88,7 +86,7 @@ Emits a {AccountCreated} event. * `accountId` (*uint128*) - The id of the account whose permission was renounced. * `permission` (*bytes32*) - The bytes32 identifier of the permission. Emits a {PermissionRevoked} event. -### hasPermission +#### hasPermission ```solidity function hasPermission(uint128 accountId, bytes32 permission, address user) external view returns (bool hasPermission) @@ -103,7 +101,7 @@ Emits a {AccountCreated} event. **Returns** * `hasPermission` (*bool*) - A boolean with the response of the query. -### isAuthorized +#### isAuthorized ```solidity function isAuthorized(uint128 accountId, bytes32 permission, address target) external view returns (bool isAuthorized) @@ -118,7 +116,7 @@ Emits a {AccountCreated} event. **Returns** * `isAuthorized` (*bool*) - A boolean with the response of the query. -### getAccountTokenAddress +#### getAccountTokenAddress ```solidity function getAccountTokenAddress() external view returns (address accountNftToken) @@ -128,7 +126,7 @@ Emits a {AccountCreated} event. **Returns** * `accountNftToken` (*address*) - The address of the account token. -### getAccountOwner +#### getAccountOwner ```solidity function getAccountOwner(uint128 accountId) external view returns (address owner) @@ -141,7 +139,7 @@ Emits a {AccountCreated} event. **Returns** * `owner` (*address*) - The owner of the given account id. -### getAccountLastInteraction +#### getAccountLastInteraction ```solidity function getAccountLastInteraction(uint128 accountId) external view returns (uint256 timestamp) @@ -155,7 +153,7 @@ Emits a {AccountCreated} event. **Returns** * `timestamp` (*uint256*) - The unix timestamp of the last time a permissioned action occured with the account -### AccountCreated +#### AccountCreated ```solidity event AccountCreated(uint128 accountId, address owner) @@ -167,7 +165,7 @@ Emits a {AccountCreated} event. * `accountId` (*uint128*) - The id of the account. * `owner` (*address*) - The address that owns the created account. -### PermissionGranted +#### PermissionGranted ```solidity event PermissionGranted(uint128 accountId, bytes32 permission, address user, address sender) @@ -181,7 +179,7 @@ Emits a {AccountCreated} event. * `user` (*address*) - The target address to whom the permission was granted. * `sender` (*address*) - The Address that granted the permission. -### PermissionRevoked +#### PermissionRevoked ```solidity event PermissionRevoked(uint128 accountId, bytes32 permission, address user, address sender) @@ -195,9 +193,9 @@ Emits a {AccountCreated} event. * `user` (*address*) - The target address for which the permission was revoked. * `sender` (*address*) - The address that revoked the permission. -## Account Token Module +### Account Token Module -### isInitialized +#### isInitialized ```solidity function isInitialized() external returns (bool) @@ -207,7 +205,7 @@ Emits a {AccountCreated} event. **Returns** * `[0]` (*bool*) - A boolean with the result of the query. -### initialize +#### initialize ```solidity function initialize(string tokenName, string tokenSymbol, string uri) external @@ -215,7 +213,7 @@ Emits a {AccountCreated} event. Initializes the token with name, symbol, and uri. -### mint +#### mint ```solidity function mint(address to, uint256 tokenId) external @@ -227,7 +225,7 @@ Emits a {AccountCreated} event. * `to` (*address*) - The address to receive the newly minted tokens. * `tokenId` (*uint256*) - The ID of the newly minted token -### safeMint +#### safeMint ```solidity function safeMint(address to, uint256 tokenId, bytes data) external @@ -240,7 +238,7 @@ Emits a {AccountCreated} event. * `tokenId` (*uint256*) - The ID of the newly minted token * `data` (*bytes*) - any data which should be sent to the receiver -### burn +#### burn ```solidity function burn(uint256 tokenId) external @@ -251,7 +249,7 @@ Emits a {AccountCreated} event. **Parameters** * `tokenId` (*uint256*) - The token to burn -### setAllowance +#### setAllowance ```solidity function setAllowance(uint256 tokenId, address spender) external @@ -263,7 +261,7 @@ Emits a {AccountCreated} event. * `tokenId` (*uint256*) - The token which should be allowed to spender * `spender` (*address*) - The address that is given allowance. -### setBaseTokenURI +#### setBaseTokenURI ```solidity function setBaseTokenURI(string uri) external @@ -274,7 +272,7 @@ Emits a {AccountCreated} event. **Parameters** * `uri` (*string*) - The new base token uri -### totalSupply +#### totalSupply ```solidity function totalSupply() external view returns (uint256) @@ -282,7 +280,7 @@ Emits a {AccountCreated} event. Returns the total amount of tokens stored by the contract. -### tokenOfOwnerByIndex +#### tokenOfOwnerByIndex ```solidity function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256) @@ -295,7 +293,7 @@ Requirements: - `owner` must be a valid address - `index` must be less than the balance of the tokens for the owner -### tokenByIndex +#### tokenByIndex ```solidity function tokenByIndex(uint256 index) external view returns (uint256) @@ -307,7 +305,7 @@ Use along with {totalSupply} to enumerate all tokens. Requirements: - `index` must be less than the total supply of the tokens -### balanceOf +#### balanceOf ```solidity function balanceOf(address holder) external view returns (uint256 balance) @@ -319,7 +317,7 @@ Requirements: - `holder` must be a valid address -### ownerOf +#### ownerOf ```solidity function ownerOf(uint256 tokenId) external view returns (address owner) @@ -331,7 +329,7 @@ Requirements: - `tokenId` must exist. -### safeTransferFrom +#### safeTransferFrom ```solidity function safeTransferFrom(address from, address to, uint256 tokenId, bytes data) external @@ -349,7 +347,7 @@ Requirements: Emits a {Transfer} event. -### safeTransferFrom +#### safeTransferFrom ```solidity function safeTransferFrom(address from, address to, uint256 tokenId) external @@ -368,7 +366,7 @@ Requirements: Emits a {Transfer} event. -### transferFrom +#### transferFrom ```solidity function transferFrom(address from, address to, uint256 tokenId) external @@ -387,7 +385,7 @@ Requirements: Emits a {Transfer} event. -### approve +#### approve ```solidity function approve(address to, uint256 tokenId) external @@ -405,7 +403,7 @@ Requirements: Emits an {Approval} event. -### setApprovalForAll +#### setApprovalForAll ```solidity function setApprovalForAll(address operator, bool approved) external @@ -420,7 +418,7 @@ Requirements: Emits an {ApprovalForAll} event. -### getApproved +#### getApproved ```solidity function getApproved(uint256 tokenId) external view returns (address operator) @@ -432,7 +430,7 @@ Requirements: - `tokenId` must exist. -### isApprovedForAll +#### isApprovedForAll ```solidity function isApprovedForAll(address owner, address operator) external view returns (bool) @@ -442,7 +440,7 @@ Requirements: See {setApprovalForAll} -### Transfer +#### Transfer ```solidity event Transfer(address from, address to, uint256 tokenId) @@ -450,7 +448,7 @@ See {setApprovalForAll} Emitted when `tokenId` token is transferred from `from` to `to`. -### Approval +#### Approval ```solidity event Approval(address owner, address approved, uint256 tokenId) @@ -458,7 +456,7 @@ See {setApprovalForAll} Emitted when `owner` enables `approved` to manage the `tokenId` token. -### ApprovalForAll +#### ApprovalForAll ```solidity event ApprovalForAll(address owner, address operator, bool approved) @@ -466,9 +464,9 @@ See {setApprovalForAll} Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets. -## Associate Debt Module +### Associate Debt Module -### associateDebt +#### associateDebt ```solidity function associateDebt(uint128 marketId, uint128 poolId, address collateralType, uint128 accountId, uint256 amount) external returns (int256 debtAmount) @@ -494,7 +492,7 @@ other accounts would be left with no change to their debt, however. **Returns** * `debtAmount` (*int256*) - The updated debt of the position, denominated with 18 decimals of precision. -### DebtAssociated +#### DebtAssociated ```solidity event DebtAssociated(uint128 marketId, uint128 poolId, address collateralType, uint128 accountId, uint256 amount, int256 updatedDebt) @@ -510,9 +508,9 @@ other accounts would be left with no change to their debt, however. * `amount` (*uint256*) - The amount of debt being associated with the specified account, denominated with 18 decimals of precision. * `updatedDebt` (*int256*) - The total updated debt of the account, denominated with 18 decimals of precision -## Collateral Configuration Module +### Collateral Configuration Module -### configureCollateral +#### configureCollateral ```solidity function configureCollateral(struct CollateralConfiguration.Data config) external @@ -523,7 +521,7 @@ other accounts would be left with no change to their debt, however. **Parameters** * `config` (*struct CollateralConfiguration.Data*) - The CollateralConfiguration object describing the new configuration. Requirements: - `msg.sender` must be the owner of the system. Emits a {CollateralConfigured} event. -### getCollateralConfigurations +#### getCollateralConfigurations ```solidity function getCollateralConfigurations(bool hideDisabled) external view returns (struct CollateralConfiguration.Data[] collaterals) @@ -538,7 +536,7 @@ other accounts would be left with no change to their debt, however. **Returns** * `collaterals` (*struct CollateralConfiguration.Data[]*) - The list of collateral configuration objects set in the system. -### getCollateralConfiguration +#### getCollateralConfiguration ```solidity function getCollateralConfiguration(address collateralType) external view returns (struct CollateralConfiguration.Data collateral) @@ -551,7 +549,7 @@ other accounts would be left with no change to their debt, however. **Returns** * `collateral` (*struct CollateralConfiguration.Data*) - The configuration object describing the given collateral. -### getCollateralPrice +#### getCollateralPrice ```solidity function getCollateralPrice(address collateralType) external view returns (uint256 priceD18) @@ -565,7 +563,7 @@ other accounts would be left with no change to their debt, however. **Returns** * `priceD18` (*uint256*) - The price of the given collateral, denominated with 18 decimals of precision. -### CollateralConfigured +#### CollateralConfigured ```solidity event CollateralConfigured(address collateralType, struct CollateralConfiguration.Data config) @@ -577,9 +575,9 @@ other accounts would be left with no change to their debt, however. * `collateralType` (*address*) - The address of the collateral type that was just configured. * `config` (*struct CollateralConfiguration.Data*) - The object with the newly configured details. -## Collateral Module +### Collateral Module -### deposit +#### deposit ```solidity function deposit(uint128 accountId, address collateralType, uint256 tokenAmount) external @@ -594,7 +592,7 @@ other accounts would be left with no change to their debt, however. * `collateralType` (*address*) - The address of the token to be deposited. * `tokenAmount` (*uint256*) - The amount being deposited, denominated in the token's native decimal representation. Emits a {Deposited} event. -### withdraw +#### withdraw ```solidity function withdraw(uint128 accountId, address collateralType, uint256 tokenAmount) external @@ -607,7 +605,7 @@ other accounts would be left with no change to their debt, however. * `collateralType` (*address*) - The address of the token to be withdrawn. * `tokenAmount` (*uint256*) - The amount being withdrawn, denominated in the token's native decimal representation. Requirements: - `msg.sender` must be the owner of the account, have the `ADMIN` permission, or have the `WITHDRAW` permission. Emits a {Withdrawn} event. -### getAccountCollateral +#### getAccountCollateral ```solidity function getAccountCollateral(uint128 accountId, address collateralType) external view returns (uint256 totalDeposited, uint256 totalAssigned, uint256 totalLocked) @@ -623,7 +621,7 @@ other accounts would be left with no change to their debt, however. * `totalDeposited` (*uint256*) - The total collateral deposited in the account, denominated with 18 decimals of precision. * `totalAssigned` (*uint256*) - The amount of collateral in the account that is delegated to pools, denominated with 18 decimals of precision. * `totalLocked` (*uint256*) - The amount of collateral in the account that cannot currently be undelegated from a pool, denominated with 18 decimals of precision. -### getAccountAvailableCollateral +#### getAccountAvailableCollateral ```solidity function getAccountAvailableCollateral(uint128 accountId, address collateralType) external view returns (uint256 amountD18) @@ -637,7 +635,7 @@ other accounts would be left with no change to their debt, however. **Returns** * `amountD18` (*uint256*) - The amount of collateral that is available for withdrawal or delegation, denominated with 18 decimals of precision. -### cleanExpiredLocks +#### cleanExpiredLocks ```solidity function cleanExpiredLocks(uint128 accountId, address collateralType, uint256 offset, uint256 count) external returns (uint256 cleared) @@ -653,7 +651,7 @@ other accounts would be left with no change to their debt, however. **Returns** * `cleared` (*uint256*) - the number of locks that were actually expired (and therefore cleared) -### getLocks +#### getLocks ```solidity function getLocks(uint128 accountId, address collateralType, uint256 offset, uint256 count) external view returns (struct CollateralLock.Data[] locks) @@ -667,7 +665,7 @@ other accounts would be left with no change to their debt, however. * `offset` (*uint256*) - The index of the first lock to read * `count` (*uint256*) - The number of slots to check for cleaning locks. Set to 0 to read all locks after offset -### createLock +#### createLock ```solidity function createLock(uint128 accountId, address collateralType, uint256 amount, uint64 expireTimestamp) external @@ -684,7 +682,7 @@ Collateral locks are initially intended for the Synthetix v2 to v3 migration, bu * `amount` (*uint256*) - The amount of collateral tokens to wrap in the lock being created, denominated with 18 decimals of precision. * `expireTimestamp` (*uint64*) - The date in which the lock will become clearable. -### Deposited +#### Deposited ```solidity event Deposited(uint128 accountId, address collateralType, uint256 tokenAmount, address sender) @@ -698,7 +696,7 @@ Collateral locks are initially intended for the Synthetix v2 to v3 migration, bu * `tokenAmount` (*uint256*) - The amount of collateral that was deposited, denominated in the token's native decimal representation. * `sender` (*address*) - The address of the account that triggered the deposit. -### CollateralLockCreated +#### CollateralLockCreated ```solidity event CollateralLockCreated(uint128 accountId, address collateralType, uint256 tokenAmount, uint64 expireTimestamp) @@ -712,7 +710,7 @@ Collateral locks are initially intended for the Synthetix v2 to v3 migration, bu * `tokenAmount` (*uint256*) - The amount of collateral that was locked, demoninated in system units (1e18) * `expireTimestamp` (*uint64*) - unix timestamp at which the lock is due to expire -### CollateralLockExpired +#### CollateralLockExpired ```solidity event CollateralLockExpired(uint128 accountId, address collateralType, uint256 tokenAmount, uint64 expireTimestamp) @@ -726,7 +724,7 @@ Collateral locks are initially intended for the Synthetix v2 to v3 migration, bu * `tokenAmount` (*uint256*) - The amount of collateral that was unlocked, demoninated in system units (1e18) * `expireTimestamp` (*uint64*) - unix timestamp at which the unlock is due to expire -### Withdrawn +#### Withdrawn ```solidity event Withdrawn(uint128 accountId, address collateralType, uint256 tokenAmount, address sender) @@ -740,9 +738,32 @@ Collateral locks are initially intended for the Synthetix v2 to v3 migration, bu * `tokenAmount` (*uint256*) - The amount of collateral that was withdrawn, denominated in the token's native decimal representation. * `sender` (*address*) - The address of the account that triggered the withdrawal. -## IssueUSD Module +### Cross ChainUSD Module + +#### transferCrossChain + + ```solidity + function transferCrossChain(uint64 destChainId, uint256 amount) external payable returns (uint256 gasTokenUsed) + ``` + + Allows users to transfer tokens cross-chain using CCIP. + +**Parameters** +* `destChainId` (*uint64*) - The id of the chain where tokens are to be transferred to. +* `amount` (*uint256*) - The amount of tokens to be transferred, denominated with 18 decimals of precision. + +**Returns** +* `gasTokenUsed` (*uint256*) - The amount of fees paid in the cross-chain transfer, denominated with 18 decimals of precision. + +#### TransferCrossChainInitiated + + ```solidity + event TransferCrossChainInitiated(uint64 destChainId, uint256 amount, address sender) + ``` -### mintUsd +### IssueUSD Module + +#### mintUsd ```solidity function mintUsd(uint128 accountId, uint128 poolId, address collateralType, uint256 amount) external @@ -756,7 +777,7 @@ Collateral locks are initially intended for the Synthetix v2 to v3 migration, bu * `collateralType` (*address*) - The address of the collateral that will be used to back up the mint. * `amount` (*uint256*) - The amount of snxUSD to be minted, denominated with 18 decimals of precision. Requirements: - `msg.sender` must be the owner of the account, have the `ADMIN` permission, or have the `MINT` permission. - After minting, the collateralization ratio of the liquidity position must not be below the target collateralization ratio for the corresponding collateral type. Emits a {UsdMinted} event. -### burnUsd +#### burnUsd ```solidity function burnUsd(uint128 accountId, uint128 poolId, address collateralType, uint256 amount) external @@ -770,7 +791,7 @@ Collateral locks are initially intended for the Synthetix v2 to v3 migration, bu * `collateralType` (*address*) - The address of the collateral that was used to back up the snxUSD. * `amount` (*uint256*) - The amount of snxUSD to be burnt, denominated with 18 decimals of precision. Emits a {UsdMinted} event. -### UsdMinted +#### UsdMinted ```solidity event UsdMinted(uint128 accountId, uint128 poolId, address collateralType, uint256 amount, address sender) @@ -785,7 +806,7 @@ Collateral locks are initially intended for the Synthetix v2 to v3 migration, bu * `amount` (*uint256*) - The amount of snxUSD emitted, denominated with 18 decimals of precision. * `sender` (*address*) - The address that triggered the operation. -### UsdBurned +#### UsdBurned ```solidity event UsdBurned(uint128 accountId, uint128 poolId, address collateralType, uint256 amount, address sender) @@ -800,15 +821,15 @@ Collateral locks are initially intended for the Synthetix v2 to v3 migration, bu * `amount` (*uint256*) - The amount of snxUSD burned, denominated with 18 decimals of precision. * `sender` (*address*) - The address that triggered the operation. -### IssuanceFeePaid +#### IssuanceFeePaid ```solidity event IssuanceFeePaid(uint128 accountId, uint128 poolId, address collateralType, uint256 feeAmount) ``` -## Liquidation Module +### Liquidation Module -### liquidate +#### liquidate ```solidity function liquidate(uint128 accountId, uint128 poolId, address collateralType, uint128 liquidateAsAccountId) external returns (struct ILiquidationModule.LiquidationData liquidationData) @@ -824,7 +845,7 @@ Collateral locks are initially intended for the Synthetix v2 to v3 migration, bu **Returns** * `liquidationData` (*struct ILiquidationModule.LiquidationData*) - Information about the position that was liquidated. -### liquidateVault +#### liquidateVault ```solidity function liquidateVault(uint128 poolId, address collateralType, uint128 liquidateAsAccountId, uint256 maxUsd) external returns (struct ILiquidationModule.LiquidationData liquidationData) @@ -844,7 +865,7 @@ Will only liquidate a portion of the debt for the vault if `maxUsd` is supplied. **Returns** * `liquidationData` (*struct ILiquidationModule.LiquidationData*) - Information about the vault that was liquidated. -### isPositionLiquidatable +#### isPositionLiquidatable ```solidity function isPositionLiquidatable(uint128 accountId, uint128 poolId, address collateralType) external returns (bool canLiquidate) @@ -859,7 +880,7 @@ Will only liquidate a portion of the debt for the vault if `maxUsd` is supplied. **Returns** * `canLiquidate` (*bool*) - A boolean with the response to the query. -### isVaultLiquidatable +#### isVaultLiquidatable ```solidity function isVaultLiquidatable(uint128 poolId, address collateralType) external returns (bool canVaultLiquidate) @@ -874,7 +895,7 @@ Will only liquidate a portion of the debt for the vault if `maxUsd` is supplied. **Returns** * `canVaultLiquidate` (*bool*) - A boolean with the response to the query. -### Liquidation +#### Liquidation ```solidity event Liquidation(uint128 accountId, uint128 poolId, address collateralType, struct ILiquidationModule.LiquidationData liquidationData, uint128 liquidateAsAccountId, address sender) @@ -890,7 +911,7 @@ Will only liquidate a portion of the debt for the vault if `maxUsd` is supplied. * `liquidateAsAccountId` (*uint128*) - Account id that will receive the rewards from the liquidation. * `sender` (*address*) - The address of the account that is triggering the liquidation. -### VaultLiquidation +#### VaultLiquidation ```solidity event VaultLiquidation(uint128 poolId, address collateralType, struct ILiquidationModule.LiquidationData liquidationData, uint128 liquidateAsAccountId, address sender) @@ -905,9 +926,9 @@ Will only liquidate a portion of the debt for the vault if `maxUsd` is supplied. * `liquidateAsAccountId` (*uint128*) - Account id that will receive the rewards from the liquidation. * `sender` (*address*) - The address of the account that is triggering the liquidation. -## Market Collateral Module +### Market Collateral Module -### depositMarketCollateral +#### depositMarketCollateral ```solidity function depositMarketCollateral(uint128 marketId, address collateralType, uint256 amount) external @@ -920,7 +941,7 @@ Will only liquidate a portion of the debt for the vault if `maxUsd` is supplied. * `collateralType` (*address*) - The address of the collateral that was deposited in the market. * `amount` (*uint256*) - The amount of collateral that was deposited, denominated in the token's native decimal representation. -### withdrawMarketCollateral +#### withdrawMarketCollateral ```solidity function withdrawMarketCollateral(uint128 marketId, address collateralType, uint256 amount) external @@ -933,7 +954,7 @@ Will only liquidate a portion of the debt for the vault if `maxUsd` is supplied. * `collateralType` (*address*) - The address of the collateral that was withdrawn from the market. * `amount` (*uint256*) - The amount of collateral that was withdrawn, denominated in the token's native decimal representation. -### configureMaximumMarketCollateral +#### configureMaximumMarketCollateral ```solidity function configureMaximumMarketCollateral(uint128 marketId, address collateralType, uint256 amount) external @@ -946,7 +967,7 @@ Will only liquidate a portion of the debt for the vault if `maxUsd` is supplied. * `collateralType` (*address*) - The address of the collateral for which the maximum is to be applied. * `amount` (*uint256*) - The amount that is to be set as the new maximum, denominated with 18 decimals of precision. -### getMaximumMarketCollateral +#### getMaximumMarketCollateral ```solidity function getMaximumMarketCollateral(uint128 marketId, address collateralType) external returns (uint256 amountD18) @@ -960,7 +981,7 @@ Will only liquidate a portion of the debt for the vault if `maxUsd` is supplied. **Returns** * `amountD18` (*uint256*) - The maximum amount of collateral set for the market, denominated with 18 decimals of precision. -### getMarketCollateralAmount +#### getMarketCollateralAmount ```solidity function getMarketCollateralAmount(uint128 marketId, address collateralType) external view returns (uint256 amountD18) @@ -974,7 +995,7 @@ Will only liquidate a portion of the debt for the vault if `maxUsd` is supplied. **Returns** * `amountD18` (*uint256*) - The total amount of collateral of this type delegated to the market, denominated with 18 decimals of precision. -### getMarketCollateralValue +#### getMarketCollateralValue ```solidity function getMarketCollateralValue(uint128 marketId) external returns (uint256 valueD18) @@ -988,7 +1009,7 @@ Will only liquidate a portion of the debt for the vault if `maxUsd` is supplied. **Returns** * `valueD18` (*uint256*) - The total value of collateral deposited by the market, denominated with 18 decimals of precision. -### MarketCollateralDeposited +#### MarketCollateralDeposited ```solidity event MarketCollateralDeposited(uint128 marketId, address collateralType, uint256 tokenAmount, address sender) @@ -1002,7 +1023,7 @@ Will only liquidate a portion of the debt for the vault if `maxUsd` is supplied. * `tokenAmount` (*uint256*) - The amount of tokens that were deposited, denominated in the token's native decimal representation. * `sender` (*address*) - The address that triggered the deposit. -### MarketCollateralWithdrawn +#### MarketCollateralWithdrawn ```solidity event MarketCollateralWithdrawn(uint128 marketId, address collateralType, uint256 tokenAmount, address sender) @@ -1016,7 +1037,7 @@ Will only liquidate a portion of the debt for the vault if `maxUsd` is supplied. * `tokenAmount` (*uint256*) - The amount of tokens that were withdrawn, denominated in the token's native decimal representation. * `sender` (*address*) - The address that triggered the withdrawal. -### MaximumMarketCollateralConfigured +#### MaximumMarketCollateralConfigured ```solidity event MaximumMarketCollateralConfigured(uint128 marketId, address collateralType, uint256 systemAmount, address owner) @@ -1030,9 +1051,9 @@ Will only liquidate a portion of the debt for the vault if `maxUsd` is supplied. * `systemAmount` (*uint256*) - The amount to which the maximum was set, denominated with 18 decimals of precision. * `owner` (*address*) - The owner of the system, which triggered the configuration change. -## Market Manager Module +### Market Manager Module -### registerMarket +#### registerMarket ```solidity function registerMarket(address market) external returns (uint128 newMarketId) @@ -1047,7 +1068,7 @@ Will only liquidate a portion of the debt for the vault if `maxUsd` is supplied. **Returns** * `newMarketId` (*uint128*) - The id with which the market will be registered in the system. -### depositMarketUsd +#### depositMarketUsd ```solidity function depositMarketUsd(uint128 marketId, address target, uint256 amount) external returns (uint256 feeAmount) @@ -1065,7 +1086,7 @@ See `IMarket`. **Returns** * `feeAmount` (*uint256*) - the amount of fees paid (billed as additional debt towards liquidity providers) -### withdrawMarketUsd +#### withdrawMarketUsd ```solidity function withdrawMarketUsd(uint128 marketId, address target, uint256 amount) external returns (uint256 feeAmount) @@ -1083,7 +1104,7 @@ See `IMarket`. **Returns** * `feeAmount` (*uint256*) - the amount of fees paid (billed as additional debt towards liquidity providers) -### getMarketFees +#### getMarketFees ```solidity function getMarketFees(uint128 marketId, uint256 amount) external view returns (uint256 depositFeeAmount, uint256 withdrawFeeAmount) @@ -1098,7 +1119,7 @@ See `IMarket`. **Returns** * `depositFeeAmount` (*uint256*) - the amount of USD paid for a call to `depositMarketUsd` * `withdrawFeeAmount` (*uint256*) - the amount of USD paid for a call to `withdrawMarketUsd` -### getWithdrawableMarketUsd +#### getWithdrawableMarketUsd ```solidity function getWithdrawableMarketUsd(uint128 marketId) external view returns (uint256 withdrawableD18) @@ -1111,7 +1132,7 @@ See `IMarket`. **Returns** * `withdrawableD18` (*uint256*) - The total amount of snxUSD that the market could withdraw at the time of the query, denominated with 18 decimals of precision. -### getMarketNetIssuance +#### getMarketNetIssuance ```solidity function getMarketNetIssuance(uint128 marketId) external view returns (int128 issuanceD18) @@ -1124,7 +1145,7 @@ See `IMarket`. **Returns** * `issuanceD18` (*int128*) - The net issuance of the market, denominated with 18 decimals of precision. -### getMarketReportedDebt +#### getMarketReportedDebt ```solidity function getMarketReportedDebt(uint128 marketId) external view returns (uint256 reportedDebtD18) @@ -1137,7 +1158,7 @@ See `IMarket`. **Returns** * `reportedDebtD18` (*uint256*) - The market's reported debt, denominated with 18 decimals of precision. -### getMarketTotalDebt +#### getMarketTotalDebt ```solidity function getMarketTotalDebt(uint128 marketId) external view returns (int256 totalDebtD18) @@ -1150,7 +1171,7 @@ See `IMarket`. **Returns** * `totalDebtD18` (*int256*) - The total debt of the market, denominated with 18 decimals of precision. -### getMarketCollateral +#### getMarketCollateral ```solidity function getMarketCollateral(uint128 marketId) external view returns (uint256 valueD18) @@ -1163,7 +1184,7 @@ See `IMarket`. **Returns** * `valueD18` (*uint256*) - The market's total snxUSD value of collateral, denominated with 18 decimals of precision. -### getMarketDebtPerShare +#### getMarketDebtPerShare ```solidity function getMarketDebtPerShare(uint128 marketId) external returns (int256 debtPerShareD18) @@ -1178,7 +1199,7 @@ See `IMarket`. **Returns** * `debtPerShareD18` (*int256*) - The market's debt per share value, denominated with 18 decimals of precision. -### isMarketCapacityLocked +#### isMarketCapacityLocked ```solidity function isMarketCapacityLocked(uint128 marketId) external view returns (bool isLocked) @@ -1191,7 +1212,7 @@ See `IMarket`. **Returns** * `isLocked` (*bool*) - A boolean that is true if the market's capacity is locked at the time of the query. -### getUsdToken +#### getUsdToken ```solidity function getUsdToken() external view returns (contract IERC20) @@ -1199,7 +1220,7 @@ See `IMarket`. Returns the USD token associated with this synthetix core system -### getOracleManager +#### getOracleManager ```solidity function getOracleManager() external view returns (contract IOracleManager) @@ -1207,7 +1228,7 @@ See `IMarket`. Retrieve the systems' configured oracle manager address -### distributeDebtToPools +#### distributeDebtToPools ```solidity function distributeDebtToPools(uint128 marketId, uint256 maxIter) external returns (bool finishedDistributing) @@ -1224,7 +1245,7 @@ costs to update an account. **Returns** * `finishedDistributing` (*bool*) - whether or not all bumpable pools have been bumped and target price has been reached -### setMarketMinDelegateTime +#### setMarketMinDelegateTime ```solidity function setMarketMinDelegateTime(uint128 marketId, uint32 minDelegateTime) external @@ -1237,7 +1258,7 @@ by limiting the frequency of `delegateCollateral` (or `setPoolConfiguration`) ca * `marketId` (*uint128*) - the id of the market that wants to set delegation time. * `minDelegateTime` (*uint32*) - the minimum number of seconds between delegation calls. Note: this value must be less than the globally defined maximum minDelegateTime -### getMarketMinDelegateTime +#### getMarketMinDelegateTime ```solidity function getMarketMinDelegateTime(uint128 marketId) external view returns (uint32) @@ -1248,7 +1269,7 @@ by limiting the frequency of `delegateCollateral` (or `setPoolConfiguration`) ca **Parameters** * `marketId` (*uint128*) - the id of the market -### setMinLiquidityRatio +#### setMinLiquidityRatio ```solidity function setMinLiquidityRatio(uint128 marketId, uint256 minLiquidityRatio) external @@ -1260,7 +1281,7 @@ by limiting the frequency of `delegateCollateral` (or `setPoolConfiguration`) ca * `marketId` (*uint128*) - the id of the market * `minLiquidityRatio` (*uint256*) - The new market-specific minimum liquidity ratio, denominated with 18 decimals of precision. (100% is represented by 1 followed by 18 zeros.) -### getMinLiquidityRatio +#### getMinLiquidityRatio ```solidity function getMinLiquidityRatio(uint128 marketId) external view returns (uint256 minRatioD18) @@ -1273,8 +1294,19 @@ by limiting the frequency of `delegateCollateral` (or `setPoolConfiguration`) ca **Returns** * `minRatioD18` (*uint256*) - The current market-specific minimum liquidity ratio, denominated with 18 decimals of precision. (100% is represented by 1 followed by 18 zeros.) +#### getMarketPools -### MarketRegistered + ```solidity + function getMarketPools(uint128 marketId) external returns (uint128[] inRangePoolIds, uint128[] outRangePoolIds) + ``` + +#### getMarketPoolDebtDistribution + + ```solidity + function getMarketPoolDebtDistribution(uint128 marketId, uint128 poolId) external returns (uint256 sharesD18, uint128 totalSharesD18, int128 valuePerShareD27) + ``` + +#### MarketRegistered ```solidity event MarketRegistered(address market, uint128 marketId, address sender) @@ -1287,7 +1319,7 @@ by limiting the frequency of `delegateCollateral` (or `setPoolConfiguration`) ca * `marketId` (*uint128*) - The id with which the market was registered in the system. * `sender` (*address*) - The account that trigger the registration of the market. -### MarketUsdDeposited +#### MarketUsdDeposited ```solidity event MarketUsdDeposited(uint128 marketId, address target, uint256 amount, address market) @@ -1301,7 +1333,7 @@ by limiting the frequency of `delegateCollateral` (or `setPoolConfiguration`) ca * `amount` (*uint256*) - The amount of snxUSD deposited in the system, denominated with 18 decimals of precision. * `market` (*address*) - The address of the external market that is depositing. -### MarketUsdWithdrawn +#### MarketUsdWithdrawn ```solidity event MarketUsdWithdrawn(uint128 marketId, address target, uint256 amount, address market) @@ -1315,13 +1347,13 @@ by limiting the frequency of `delegateCollateral` (or `setPoolConfiguration`) ca * `amount` (*uint256*) - The amount of snxUSD withdrawn from the system, denominated with 18 decimals of precision. * `market` (*address*) - The address of the external market that is withdrawing. -### MarketSystemFeePaid +#### MarketSystemFeePaid ```solidity event MarketSystemFeePaid(uint128 marketId, uint256 feeAmount) ``` -### SetMinDelegateTime +#### SetMinDelegateTime ```solidity event SetMinDelegateTime(uint128 marketId, uint32 minDelegateTime) @@ -1333,7 +1365,7 @@ by limiting the frequency of `delegateCollateral` (or `setPoolConfiguration`) ca * `marketId` (*uint128*) - The id of the market that the setting is applied to * `minDelegateTime` (*uint32*) - The minimum amount of time between delegation changes -### SetMarketMinLiquidityRatio +#### SetMarketMinLiquidityRatio ```solidity event SetMarketMinLiquidityRatio(uint128 marketId, uint256 minLiquidityRatio) @@ -1345,9 +1377,9 @@ by limiting the frequency of `delegateCollateral` (or `setPoolConfiguration`) ca * `marketId` (*uint128*) - The id of the market that the setting is applied to * `minLiquidityRatio` (*uint256*) - The new market-specific minimum liquidity ratio -## Multicall Module +### Multicall Module -### multicall +#### multicall ```solidity function multicall(bytes[] data) external payable returns (bytes[] results) @@ -1363,9 +1395,9 @@ by limiting the frequency of `delegateCollateral` (or `setPoolConfiguration`) ca **Returns** * `results` (*bytes[]*) - Array of each `delegatecall`'s response corresponding to the incoming calldata array. -## Pool Configuration Module +### Pool Configuration Module -### setPreferredPool +#### setPreferredPool ```solidity function setPreferredPool(uint128 poolId) external @@ -1378,7 +1410,7 @@ by limiting the frequency of `delegateCollateral` (or `setPoolConfiguration`) ca **Parameters** * `poolId` (*uint128*) - The id of the pool that is to be set as preferred. -### addApprovedPool +#### addApprovedPool ```solidity function addApprovedPool(uint128 poolId) external @@ -1391,7 +1423,7 @@ by limiting the frequency of `delegateCollateral` (or `setPoolConfiguration`) ca **Parameters** * `poolId` (*uint128*) - The id of the pool that is to be approved. -### removeApprovedPool +#### removeApprovedPool ```solidity function removeApprovedPool(uint128 poolId) external @@ -1402,7 +1434,7 @@ by limiting the frequency of `delegateCollateral` (or `setPoolConfiguration`) ca **Parameters** * `poolId` (*uint128*) - The id of the pool that is to be no longer approved. -### getPreferredPool +#### getPreferredPool ```solidity function getPreferredPool() external view returns (uint128 poolId) @@ -1412,7 +1444,7 @@ by limiting the frequency of `delegateCollateral` (or `setPoolConfiguration`) ca **Returns** * `poolId` (*uint128*) - The id of the pool that is currently set as preferred in the system. -### getApprovedPools +#### getApprovedPools ```solidity function getApprovedPools() external view returns (uint256[] poolIds) @@ -1423,7 +1455,7 @@ by limiting the frequency of `delegateCollateral` (or `setPoolConfiguration`) ca **Returns** * `poolIds` (*uint256[]*) - An array with all of the pool ids that are approved in the system. -### PreferredPoolSet +#### PreferredPoolSet ```solidity event PreferredPoolSet(uint256 poolId) @@ -1434,7 +1466,7 @@ by limiting the frequency of `delegateCollateral` (or `setPoolConfiguration`) ca **Parameters** * `poolId` (*uint256*) - The id of the pool that was set as preferred. -### PoolApprovedAdded +#### PoolApprovedAdded ```solidity event PoolApprovedAdded(uint256 poolId) @@ -1445,7 +1477,7 @@ by limiting the frequency of `delegateCollateral` (or `setPoolConfiguration`) ca **Parameters** * `poolId` (*uint256*) - The id of the pool that was approved. -### PoolApprovedRemoved +#### PoolApprovedRemoved ```solidity event PoolApprovedRemoved(uint256 poolId) @@ -1456,9 +1488,9 @@ by limiting the frequency of `delegateCollateral` (or `setPoolConfiguration`) ca **Parameters** * `poolId` (*uint256*) - The id of the pool that is no longer approved. -## Pool Module +### Pool Module -### createPool +#### createPool ```solidity function createPool(uint128 requestedPoolId, address owner) external @@ -1470,7 +1502,7 @@ by limiting the frequency of `delegateCollateral` (or `setPoolConfiguration`) ca * `requestedPoolId` (*uint128*) - The requested id for the new pool. Reverts if the id is not available. * `owner` (*address*) - The address that will own the newly created pool. -### setPoolConfiguration +#### setPoolConfiguration ```solidity function setPoolConfiguration(uint128 poolId, struct MarketConfiguration.Data[] marketDistribution) external @@ -1485,7 +1517,7 @@ Incoming market ids need to be provided in ascending order. * `poolId` (*uint128*) - The id of the pool whose configuration is being set. * `marketDistribution` (*struct MarketConfiguration.Data[]*) - The array of market configuration objects that define the list of markets that are connected to the system. -### getPoolConfiguration +#### getPoolConfiguration ```solidity function getPoolConfiguration(uint128 poolId) external view returns (struct MarketConfiguration.Data[] markets) @@ -1498,7 +1530,7 @@ Incoming market ids need to be provided in ascending order. **Returns** * `markets` (*struct MarketConfiguration.Data[]*) - The array of MarketConfiguration objects that describe the pool's configuration. -### setPoolName +#### setPoolName ```solidity function setPoolName(uint128 poolId, string name) external @@ -1510,7 +1542,7 @@ Incoming market ids need to be provided in ascending order. * `poolId` (*uint128*) - The id of the pool whose name is being set. * `name` (*string*) - The new name to give to the pool. -### getPoolName +#### getPoolName ```solidity function getPoolName(uint128 poolId) external view returns (string poolName) @@ -1523,7 +1555,7 @@ Incoming market ids need to be provided in ascending order. **Returns** * `poolName` (*string*) - The current name of the pool. -### nominatePoolOwner +#### nominatePoolOwner ```solidity function nominatePoolOwner(address nominatedOwner, uint128 poolId) external @@ -1535,7 +1567,7 @@ Incoming market ids need to be provided in ascending order. * `nominatedOwner` (*address*) - The address to nominate os the new pool owner. * `poolId` (*uint128*) - The id whose ownership is being transferred. -### acceptPoolOwnership +#### acceptPoolOwnership ```solidity function acceptPoolOwnership(uint128 poolId) external @@ -1546,7 +1578,7 @@ Incoming market ids need to be provided in ascending order. **Parameters** * `poolId` (*uint128*) - The id of the pool for which the caller is to accept ownership. -### revokePoolNomination +#### revokePoolNomination ```solidity function revokePoolNomination(uint128 poolId) external @@ -1557,7 +1589,7 @@ Incoming market ids need to be provided in ascending order. **Parameters** * `poolId` (*uint128*) - The id of the pool for which the new owner nomination is to be revoked. -### renouncePoolNomination +#### renouncePoolNomination ```solidity function renouncePoolNomination(uint128 poolId) external @@ -1568,7 +1600,7 @@ Incoming market ids need to be provided in ascending order. **Parameters** * `poolId` (*uint128*) - The id of the pool for which the caller is renouncing ownership nomination. -### getPoolOwner +#### getPoolOwner ```solidity function getPoolOwner(uint128 poolId) external view returns (address owner) @@ -1581,7 +1613,7 @@ Incoming market ids need to be provided in ascending order. **Returns** * `owner` (*address*) - The current owner of the pool. -### getNominatedPoolOwner +#### getNominatedPoolOwner ```solidity function getNominatedPoolOwner(uint128 poolId) external view returns (address nominatedOwner) @@ -1594,7 +1626,7 @@ Incoming market ids need to be provided in ascending order. **Returns** * `nominatedOwner` (*address*) - The current nominated owner of the pool. -### setMinLiquidityRatio +#### setMinLiquidityRatio ```solidity function setMinLiquidityRatio(uint256 minLiquidityRatio) external @@ -1605,7 +1637,7 @@ Incoming market ids need to be provided in ascending order. **Parameters** * `minLiquidityRatio` (*uint256*) - The new system-wide minimum liquidity ratio, denominated with 18 decimals of precision. (100% is represented by 1 followed by 18 zeros.) -### getMinLiquidityRatio +#### getMinLiquidityRatio ```solidity function getMinLiquidityRatio() external view returns (uint256 minRatioD18) @@ -1615,7 +1647,7 @@ Incoming market ids need to be provided in ascending order. **Returns** * `minRatioD18` (*uint256*) - The current system-wide minimum liquidity ratio, denominated with 18 decimals of precision. (100% is represented by 1 followed by 18 zeros.) -### rebalancePool +#### rebalancePool ```solidity function rebalancePool(uint128 poolId, address optionalCollateralType) external @@ -1627,7 +1659,7 @@ Incoming market ids need to be provided in ascending order. * `poolId` (*uint128*) - the pool to rebalance * `optionalCollateralType` (*address*) - in addition to rebalancing the pool, calculate updated collaterals and debts for the specified vault -### PoolCreated +#### PoolCreated ```solidity event PoolCreated(uint128 poolId, address owner, address sender) @@ -1640,7 +1672,7 @@ Incoming market ids need to be provided in ascending order. * `owner` (*address*) - The owner of the newly created pool. * `sender` (*address*) - The address that triggered the creation of the pool. -### PoolOwnerNominated +#### PoolOwnerNominated ```solidity event PoolOwnerNominated(uint128 poolId, address nominatedOwner, address owner) @@ -1653,7 +1685,7 @@ Incoming market ids need to be provided in ascending order. * `nominatedOwner` (*address*) - The address that was nominated as the new owner of the pool. * `owner` (*address*) - The address of the current owner of the pool. -### PoolOwnershipAccepted +#### PoolOwnershipAccepted ```solidity event PoolOwnershipAccepted(uint128 poolId, address owner) @@ -1665,7 +1697,7 @@ Incoming market ids need to be provided in ascending order. * `poolId` (*uint128*) - The id of the pool for which the owner nomination was accepted. * `owner` (*address*) - The address of the new owner of the pool, which accepted the nomination. -### PoolNominationRevoked +#### PoolNominationRevoked ```solidity event PoolNominationRevoked(uint128 poolId, address owner) @@ -1677,7 +1709,7 @@ Incoming market ids need to be provided in ascending order. * `poolId` (*uint128*) - The id of the pool in which the nomination was revoked. * `owner` (*address*) - The current owner of the pool. -### PoolNominationRenounced +#### PoolNominationRenounced ```solidity event PoolNominationRenounced(uint128 poolId, address owner) @@ -1689,7 +1721,7 @@ Incoming market ids need to be provided in ascending order. * `poolId` (*uint128*) - The id of the pool for which the owner nomination was renounced. * `owner` (*address*) - The current owner of the pool. -### PoolNameUpdated +#### PoolNameUpdated ```solidity event PoolNameUpdated(uint128 poolId, string name, address sender) @@ -1702,7 +1734,7 @@ Incoming market ids need to be provided in ascending order. * `name` (*string*) - The new name of the pool. * `sender` (*address*) - The address that triggered the rename of the pool. -### PoolConfigurationSet +#### PoolConfigurationSet ```solidity event PoolConfigurationSet(uint128 poolId, struct MarketConfiguration.Data[] markets, address sender) @@ -1715,7 +1747,7 @@ Incoming market ids need to be provided in ascending order. * `markets` (*struct MarketConfiguration.Data[]*) - Array of configuration data of the markets that were connected to the pool. * `sender` (*address*) - The address that triggered the pool configuration. -### SetMinLiquidityRatio +#### SetMinLiquidityRatio ```solidity event SetMinLiquidityRatio(uint256 minLiquidityRatio) @@ -1726,9 +1758,9 @@ Incoming market ids need to be provided in ascending order. **Parameters** * `minLiquidityRatio` (*uint256*) - The new system-wide minimum liquidity ratio -## Rewards Manager Module +### Rewards Manager Module -### registerRewardsDistributor +#### registerRewardsDistributor ```solidity function registerRewardsDistributor(uint128 poolId, address collateralType, address distributor) external @@ -1741,7 +1773,7 @@ Incoming market ids need to be provided in ascending order. * `collateralType` (*address*) - The address of the collateral used in the pool's rewards. * `distributor` (*address*) - The address of the reward distributor to be registered. -### removeRewardsDistributor +#### removeRewardsDistributor ```solidity function removeRewardsDistributor(uint128 poolId, address collateralType, address distributor) external @@ -1762,7 +1794,7 @@ rewards-over-time will be halted) * `collateralType` (*address*) - The address of the collateral used in the pool's rewards. * `distributor` (*address*) - The address of the reward distributor to be registered. -### distributeRewards +#### distributeRewards ```solidity function distributeRewards(uint128 poolId, address collateralType, uint256 amount, uint64 start, uint32 duration) external @@ -1779,7 +1811,7 @@ rewards-over-time will be halted) * `start` (*uint64*) - The date at which the rewards will begin to be claimable. * `duration` (*uint32*) - The period after which all distributed rewards will be claimable. -### claimRewards +#### claimRewards ```solidity function claimRewards(uint128 accountId, uint128 poolId, address collateralType, address distributor) external returns (uint256 amountClaimedD18) @@ -1795,7 +1827,7 @@ rewards-over-time will be halted) **Returns** * `amountClaimedD18` (*uint256*) - The amount of rewards that were available for the account and thus claimed. -### updateRewards +#### updateRewards ```solidity function updateRewards(uint128 poolId, address collateralType, uint128 accountId) external returns (uint256[] claimableD18, address[] distributors) @@ -1811,7 +1843,7 @@ rewards-over-time will be halted) **Returns** * `claimableD18` (*uint256[]*) - An array of ids of the reward entries that are claimable by the position. * `distributors` (*address[]*) - An array with the addresses of the reward distributors associated with the claimable rewards. -### getRewardRate +#### getRewardRate ```solidity function getRewardRate(uint128 poolId, address collateralType, address distributor) external view returns (uint256 rateD18) @@ -1827,7 +1859,7 @@ rewards-over-time will be halted) **Returns** * `rateD18` (*uint256*) - The queried rewards rate. -### RewardsDistributed +#### RewardsDistributed ```solidity event RewardsDistributed(uint128 poolId, address collateralType, address distributor, uint256 amount, uint256 start, uint256 duration) @@ -1843,7 +1875,7 @@ rewards-over-time will be halted) * `start` (*uint256*) - The date one which the rewards will begin to be claimable. * `duration` (*uint256*) - The time in which all of the distributed rewards will be claimable. -### RewardsClaimed +#### RewardsClaimed ```solidity event RewardsClaimed(uint128 accountId, uint128 poolId, address collateralType, address distributor, uint256 amount) @@ -1858,7 +1890,7 @@ rewards-over-time will be halted) * `distributor` (*address*) - The address of the rewards distributor associated with these rewards. * `amount` (*uint256*) - The amount of rewards that were claimed. -### RewardsDistributorRegistered +#### RewardsDistributorRegistered ```solidity event RewardsDistributorRegistered(uint128 poolId, address collateralType, address distributor) @@ -1871,7 +1903,7 @@ rewards-over-time will be halted) * `collateralType` (*address*) - The address of the collateral used in the pool's rewards. * `distributor` (*address*) - The address of the newly registered reward distributor. -### RewardsDistributorRemoved +#### RewardsDistributorRemoved ```solidity event RewardsDistributorRemoved(uint128 poolId, address collateralType, address distributor) @@ -1884,9 +1916,9 @@ rewards-over-time will be halted) * `collateralType` (*address*) - The address of the collateral used in the pool's rewards. * `distributor` (*address*) - The address of the registered reward distributor. -## USD Token Module +### USD Token Module -### burnWithAllowance +#### burnWithAllowance ```solidity function burnWithAllowance(address from, address spender, uint256 amount) external @@ -1899,22 +1931,18 @@ rewards-over-time will be halted) * `spender` (*address*) - The address to which the holder has given allowance to. * `amount` (*uint256*) - The amount of snxUSD to be burned, denominated with 18 decimals of precision. -### transferCrossChain +#### burn ```solidity - function transferCrossChain(uint256 destChainId, address to, uint256 amount) external returns (uint256 feesPaidD18) + function burn(uint256 amount) external ``` - Allows users to transfer tokens cross-chain using CCIP. This is disabled until _CCIP_CHAINLINK_SEND is set in UtilsModule. This is currently included for testing purposes. Functionality will change, including fee collection, as CCIP continues development. + Destroys `amount` of snxUSD tokens from the caller. This is derived from ERC20Burnable.sol and is currently included for testing purposes with CCIP token pools. **Parameters** -* `destChainId` (*uint256*) - The id of the chain where tokens are to be transferred to. -* `to` (*address*) - The destination address in the target chain. -* `amount` (*uint256*) - The amount of tokens to be transferred, denominated with 18 decimals of precision. +* `amount` (*uint256*) - The amount of snxUSD to be burned, denominated with 18 decimals of precision. -**Returns** -* `feesPaidD18` (*uint256*) - The amount of fees paid in the cross-chain transfer, denominated with 18 decimals of precision. -### isInitialized +#### isInitialized ```solidity function isInitialized() external returns (bool) @@ -1924,7 +1952,7 @@ rewards-over-time will be halted) **Returns** * `[0]` (*bool*) - A boolean with the result of the query. -### initialize +#### initialize ```solidity function initialize(string tokenName, string tokenSymbol, uint8 tokenDecimals) external @@ -1932,7 +1960,7 @@ rewards-over-time will be halted) Initializes the token with name, symbol, and decimals. -### mint +#### mint ```solidity function mint(address to, uint256 amount) external @@ -1944,7 +1972,7 @@ rewards-over-time will be halted) * `to` (*address*) - The address to receive the newly minted tokens. * `amount` (*uint256*) - The amount of tokens to mint. -### burn +#### burn ```solidity function burn(address from, uint256 amount) external @@ -1956,7 +1984,7 @@ rewards-over-time will be halted) * `from` (*address*) - The address whose tokens will be burnt. * `amount` (*uint256*) - The amount of tokens to burn. -### setAllowance +#### setAllowance ```solidity function setAllowance(address from, address spender, uint256 amount) external @@ -1969,7 +1997,7 @@ rewards-over-time will be halted) * `spender` (*address*) - The address that is given allowance. * `amount` (*uint256*) - The amount of allowance being given. -### name +#### name ```solidity function name() external view returns (string) @@ -1979,7 +2007,7 @@ rewards-over-time will be halted) **Returns** * `[0]` (*string*) - A string with the name of the token. -### symbol +#### symbol ```solidity function symbol() external view returns (string) @@ -1989,7 +2017,7 @@ rewards-over-time will be halted) **Returns** * `[0]` (*string*) - A string with the symbol of the token. -### decimals +#### decimals ```solidity function decimals() external view returns (uint8) @@ -1999,7 +2027,7 @@ rewards-over-time will be halted) **Returns** * `[0]` (*uint8*) - The number of decimals. -### totalSupply +#### totalSupply ```solidity function totalSupply() external view returns (uint256) @@ -2009,7 +2037,7 @@ rewards-over-time will be halted) **Returns** * `[0]` (*uint256*) - The total number of tokens. -### balanceOf +#### balanceOf ```solidity function balanceOf(address owner) external view returns (uint256) @@ -2022,7 +2050,7 @@ rewards-over-time will be halted) **Returns** * `[0]` (*uint256*) - The number of tokens owned by the user. -### allowance +#### allowance ```solidity function allowance(address owner, address spender) external view returns (uint256) @@ -2036,7 +2064,7 @@ rewards-over-time will be halted) **Returns** * `[0]` (*uint256*) - The amount of tokens `spender` can transfer on `owner`'s behalf. -### transfer +#### transfer ```solidity function transfer(address to, uint256 amount) external returns (bool) @@ -2050,7 +2078,7 @@ rewards-over-time will be halted) **Returns** * `[0]` (*bool*) - A boolean which is true if the operation succeeded. -### approve +#### approve ```solidity function approve(address spender, uint256 amount) external returns (bool) @@ -2064,7 +2092,7 @@ rewards-over-time will be halted) **Returns** * `[0]` (*bool*) - A boolean which is true if the operation succeeded. -### increaseAllowance +#### increaseAllowance ```solidity function increaseAllowance(address spender, uint256 addedValue) external returns (bool) @@ -2081,7 +2109,7 @@ Requirements: - `spender` cannot be the zero address. -### decreaseAllowance +#### decreaseAllowance ```solidity function decreaseAllowance(address spender, uint256 subtractedValue) external returns (bool) @@ -2100,7 +2128,7 @@ Requirements: - `spender` must have allowance for the caller of at least `subtractedValue`. -### transferFrom +#### transferFrom ```solidity function transferFrom(address from, address to, uint256 amount) external returns (bool) @@ -2116,7 +2144,7 @@ Requirements: **Returns** * `[0]` (*bool*) - A boolean which is true if the operation succeeded. -### Transfer +#### Transfer ```solidity event Transfer(address from, address to, uint256 amount) @@ -2129,7 +2157,7 @@ Requirements: * `to` (*address*) - The address that received the tokens. * `amount` (*uint256*) - The number of tokens that were transferred. -### Approval +#### Approval ```solidity event Approval(address owner, address spender, uint256 amount) @@ -2142,9 +2170,9 @@ Requirements: * `spender` (*address*) - The address that received the allowance. * `amount` (*uint256*) - The number of tokens that were added to `spender`'s allowance. -## Vault Module +### Vault Module -### delegateCollateral +#### delegateCollateral ```solidity function delegateCollateral(uint128 accountId, uint128 poolId, address collateralType, uint256 amount, uint256 leverage) external @@ -2159,7 +2187,7 @@ Requirements: * `amount` (*uint256*) - The new amount of collateral delegated in the position, denominated with 18 decimals of precision. * `leverage` (*uint256*) - The new leverage amount used in the position, denominated with 18 decimals of precision. Requirements: - `msg.sender` must be the owner of the account, have the `ADMIN` permission, or have the `DELEGATE` permission. - If increasing the amount delegated, it must not exceed the available collateral (`getAccountAvailableCollateral`) associated with the account. - If decreasing the amount delegated, the liquidity position must have a collateralization ratio greater than the target collateralization ratio for the corresponding collateral type. Emits a {DelegationUpdated} event. -### getPositionCollateralRatio +#### getPositionCollateralRatio ```solidity function getPositionCollateralRatio(uint128 accountId, uint128 poolId, address collateralType) external returns (uint256 ratioD18) @@ -2177,7 +2205,7 @@ The return value is a percentage with 18 decimals places. **Returns** * `ratioD18` (*uint256*) - The collateralization ratio of the position (collateral / debt), denominated with 18 decimals of precision. -### getPositionDebt +#### getPositionDebt ```solidity function getPositionDebt(uint128 accountId, uint128 poolId, address collateralType) external returns (int256 debtD18) @@ -2195,7 +2223,7 @@ Call this function using `callStatic` to treat it as a view function. **Returns** * `debtD18` (*int256*) - The amount of debt held by the position, denominated with 18 decimals of precision. -### getPositionCollateral +#### getPositionCollateral ```solidity function getPositionCollateral(uint128 accountId, uint128 poolId, address collateralType) external view returns (uint256 collateralAmountD18, uint256 collateralValueD18) @@ -2215,7 +2243,7 @@ collateralValue is represented as an integer with the number of decimals specifi **Returns** * `collateralAmountD18` (*uint256*) - The amount of collateral used in the position, denominated with 18 decimals of precision. * `collateralValueD18` (*uint256*) - The value of collateral used in the position, denominated with 18 decimals of precision. -### getPosition +#### getPosition ```solidity function getPosition(uint128 accountId, uint128 poolId, address collateralType) external returns (uint256 collateralAmountD18, uint256 collateralValueD18, int256 debtD18, uint256 collateralizationRatioD18) @@ -2233,7 +2261,7 @@ collateralValue is represented as an integer with the number of decimals specifi * `collateralValueD18` (*uint256*) - The value of the collateral used in the position, denominated with 18 decimals of precision. * `debtD18` (*int256*) - The amount of debt held in the position, denominated with 18 decimals of precision. * `collateralizationRatioD18` (*uint256*) - The collateralization ratio of the position (collateral / debt), denominated with 18 decimals of precision. -### getVaultDebt +#### getVaultDebt ```solidity function getVaultDebt(uint128 poolId, address collateralType) external returns (int256 debtD18) @@ -2250,7 +2278,7 @@ Call this function using `callStatic` to treat it as a view function. **Returns** * `debtD18` (*int256*) - The overall debt of the vault, denominated with 18 decimals of precision. -### getVaultCollateral +#### getVaultCollateral ```solidity function getVaultCollateral(uint128 poolId, address collateralType) external returns (uint256 collateralAmountD18, uint256 collateralValueD18) @@ -2269,7 +2297,7 @@ collateralValue is represented as an integer with the number of decimals specifi **Returns** * `collateralAmountD18` (*uint256*) - The collateral amount of the vault, denominated with 18 decimals of precision. * `collateralValueD18` (*uint256*) - The collateral value of the vault, denominated with 18 decimals of precision. -### getVaultCollateralRatio +#### getVaultCollateralRatio ```solidity function getVaultCollateralRatio(uint128 poolId, address collateralType) external returns (uint256 ratioD18) @@ -2287,7 +2315,7 @@ The return value is a percentage with 18 decimals places. **Returns** * `ratioD18` (*uint256*) - The collateralization ratio of the vault, denominated with 18 decimals of precision. -### DelegationUpdated +#### DelegationUpdated ```solidity event DelegationUpdated(uint128 accountId, uint128 poolId, address collateralType, uint256 amount, uint256 leverage, address sender) diff --git a/utils/docgen/docgen:contracts.sh b/utils/docgen/docgen:contracts.sh new file mode 100755 index 0000000000..f694cde638 --- /dev/null +++ b/utils/docgen/docgen:contracts.sh @@ -0,0 +1,45 @@ +#!/bin/bash + +ROOT=$(yarn workspace synthetix-v3 exec pwd) +OUT="$ROOT/docs/Contracts.md" +mkdir -p $ROOT/docs +touch $OUT + +echo "# Smart Contracts" > $OUT +echo "" >> $OUT + +echo "- [Synthetix Core](#synthetix-core)" >> $OUT +echo "- [Spot Market](#spot-market)" >> $OUT +echo "- [Perps Market](#perps-market)" >> $OUT +echo "- [Governance](#governance)" >> $OUT +echo "- [Oracle Manager](#oracle-manager)" >> $OUT +echo "" >> $OUT + + +echo "## Synthetix Core" >> $OUT +echo "" >> $OUT +cat $ROOT/protocol/synthetix/docs/index.md >> $OUT + +echo "## Spot Market" >> $OUT +echo "" >> $OUT +echo "- [Back to TOC](#smart-contracts)" >> $OUT +echo "" >> $OUT +cat $ROOT/markets/spot-market/docs/index.md >> $OUT + +echo "## Perps Market" >> $OUT +echo "" >> $OUT +echo "- [Back to TOC](#smart-contracts)" >> $OUT +echo "" >> $OUT +cat $ROOT/markets/perps-market/docs/index.md >> $OUT + +echo "## Governance" >> $OUT +echo "" >> $OUT +echo "- [Back to TOC](#smart-contracts)" >> $OUT +echo "" >> $OUT +cat $ROOT/protocol/governance/docs/index.md >> $OUT + +echo "## Oracle Manager" >> $OUT +echo "" >> $OUT +echo "- [Back to TOC](#smart-contracts)" >> $OUT +echo "" >> $OUT +cat $ROOT/protocol/oracle-manager/docs/index.md >> $OUT diff --git a/utils/docgen/natspec/theme/contract.hbs b/utils/docgen/natspec/theme/contract.hbs index 7611104d1f..210e847d50 100644 --- a/utils/docgen/natspec/theme/contract.hbs +++ b/utils/docgen/natspec/theme/contract.hbs @@ -10,4 +10,4 @@ {{#hsection}} {{>item}} {{/hsection}} -{{/each}} \ No newline at end of file +{{/each}} diff --git a/utils/docgen/natspec/theme/helpers.ts b/utils/docgen/natspec/theme/helpers.ts index f95d4a4bee..cdd095c74e 100644 --- a/utils/docgen/natspec/theme/helpers.ts +++ b/utils/docgen/natspec/theme/helpers.ts @@ -47,7 +47,7 @@ function getHLevel(hsublevel: number | HelperOptions, opts?: HelperOptions) { opts = hsublevel; hsublevel = 1; } - const contextHLevel: number = opts.data?.hlevel ?? 0; + const contextHLevel: number = opts.data?.hlevel ?? 1; return { opts, hlevel: contextHLevel + hsublevel }; } diff --git a/utils/docgen/natspec/theme/page.hbs b/utils/docgen/natspec/theme/page.hbs new file mode 100644 index 0000000000..793dc6f7f6 --- /dev/null +++ b/utils/docgen/natspec/theme/page.hbs @@ -0,0 +1,6 @@ +{{#each items}} +{{#hsection}} +{{>item}} +{{/hsection}} + +{{/each}} diff --git a/utils/docgen/package.json b/utils/docgen/package.json index c865e28880..a9d1066e79 100644 --- a/utils/docgen/package.json +++ b/utils/docgen/package.json @@ -7,7 +7,8 @@ "main": "index.js", "types": "index.d.ts", "scripts": { - "abis": "node ./abis.js" + "abis": "node ./abis.js", + "docgen:contracts": "./docgen:contracts.sh" }, "devDependencies": { "@usecannon/cli": "^2.4.21", From ab2c70061438caa023ee5d924a525271db22c63d Mon Sep 17 00:00:00 2001 From: Noisekit Date: Tue, 8 Aug 2023 15:02:21 +0800 Subject: [PATCH 36/63] Docgen no clean (#1752) * Ignore unnecessary subgraph build artifacts * Remove clean --- .eslintignore | 3 +++ .prettierignore | 4 +++- package.json | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/.eslintignore b/.eslintignore index 35611d2681..f5c21b47f6 100644 --- a/.eslintignore +++ b/.eslintignore @@ -6,3 +6,6 @@ utils/*/utils **/contracts/generated **/test/generated **/artifacts +**/subgraph/deployments +**/subgraph/build +**/subgraph/.bin diff --git a/.prettierignore b/.prettierignore index d58cdeafdf..59354709ba 100644 --- a/.prettierignore +++ b/.prettierignore @@ -15,7 +15,9 @@ markets/*/test/generated .yarnrc.yml lerna.json *.hbs -**/subgraph/deployments/ +**/subgraph/deployments +**/subgraph/build +**/subgraph/.bin **/artifacts/ **/cache/ **/docs/ diff --git a/package.json b/package.json index 7ee4c9971e..f2f9d1b83b 100644 --- a/package.json +++ b/package.json @@ -37,7 +37,7 @@ "publish:dev": "lerna publish --force-publish --canary --dist-tag dev --preid dev.$(git rev-parse --short HEAD)", "publish-contracts": "yarn workspaces foreach --verbose run publish-contracts", "prepublishOnly": "node ./prepublishOnly.js", - "docgen": "yarn clean && yarn workspaces foreach --verbose run docgen && yarn docgen:contracts", + "docgen": "yarn workspaces foreach --verbose run docgen && yarn docgen:contracts", "docgen:contracts": "yarn workspace @synthetixio/docgen docgen:contracts", "subgraphgen": "yarn workspaces foreach --verbose run subgraphgen" }, From 74ef2001cff16c7530c819f978603567eef06fed Mon Sep 17 00:00:00 2001 From: Sunny Vempati Date: Tue, 8 Aug 2023 09:17:36 -0500 Subject: [PATCH 37/63] Add liq reward to async order validation (#1751) * add liq reward to async order validation * lint fix --- .../interfaces/IPerpsAccountModule.sol | 12 +- .../contracts/modules/LiquidationModule.sol | 2 +- .../contracts/modules/PerpsAccountModule.sol | 23 +- .../contracts/storage/AsyncOrder.sol | 81 +++-- .../contracts/storage/PerpsAccount.sol | 40 ++- .../Orders/Order.marginValidation.test.ts | 291 ++++++++++++++++++ .../test/integration/helpers/index.ts | 1 + .../integration/helpers/requiredMargins.ts | 28 ++ 8 files changed, 440 insertions(+), 38 deletions(-) create mode 100644 markets/perps-market/test/integration/Orders/Order.marginValidation.test.ts create mode 100644 markets/perps-market/test/integration/helpers/requiredMargins.ts diff --git a/markets/perps-market/contracts/interfaces/IPerpsAccountModule.sol b/markets/perps-market/contracts/interfaces/IPerpsAccountModule.sol index e34f75bdbf..3077f50162 100644 --- a/markets/perps-market/contracts/interfaces/IPerpsAccountModule.sol +++ b/markets/perps-market/contracts/interfaces/IPerpsAccountModule.sol @@ -91,8 +91,18 @@ interface IPerpsAccountModule { * @param accountId Id of the account. * @return requiredInitialMargin initial margin req (used when withdrawing collateral). * @return requiredMaintenanceMargin maintenance margin req (used to determine liquidation threshold). + * @return totalAccumulatedLiquidationRewards sum of all liquidation rewards of if all account open positions were to be liquidated fully. + * @return maxLiquidationReward max liquidation reward the keeper would receive if account was fully liquidated. Note here that the accumulated rewards are checked against the global max/min configured liquidation rewards. */ function getRequiredMargins( uint128 accountId - ) external view returns (uint256 requiredInitialMargin, uint256 requiredMaintenanceMargin); + ) + external + view + returns ( + uint256 requiredInitialMargin, + uint256 requiredMaintenanceMargin, + uint256 totalAccumulatedLiquidationRewards, + uint256 maxLiquidationReward + ); } diff --git a/markets/perps-market/contracts/modules/LiquidationModule.sol b/markets/perps-market/contracts/modules/LiquidationModule.sol index acccd35459..19a3a54e43 100644 --- a/markets/perps-market/contracts/modules/LiquidationModule.sol +++ b/markets/perps-market/contracts/modules/LiquidationModule.sol @@ -30,7 +30,7 @@ contract LiquidationModule is ILiquidationModule, IMarketEvents { .liquidatableAccounts; PerpsAccount.Data storage account = PerpsAccount.load(accountId); if (!liquidatableAccounts.contains(accountId)) { - (bool isEligible, , , ) = account.isEligibleForLiquidation(); + (bool isEligible, , , , , ) = account.isEligibleForLiquidation(); if (isEligible) { account.flagForLiquidation(); diff --git a/markets/perps-market/contracts/modules/PerpsAccountModule.sol b/markets/perps-market/contracts/modules/PerpsAccountModule.sol index 3ea1eeadee..31ea3e1f32 100644 --- a/markets/perps-market/contracts/modules/PerpsAccountModule.sol +++ b/markets/perps-market/contracts/modules/PerpsAccountModule.sol @@ -118,9 +118,12 @@ contract PerpsAccountModule is IPerpsAccountModule { ) external view override returns (int256 withdrawableMargin) { PerpsAccount.Data storage account = PerpsAccount.load(accountId); int256 availableMargin = account.getAvailableMargin(); - (uint256 initialRequiredMargin, ) = account.getAccountRequiredMargins(); + (uint256 initialRequiredMargin, , , uint256 liquidationReward) = account + .getAccountRequiredMargins(); + + uint256 requiredMargin = initialRequiredMargin + liquidationReward; - withdrawableMargin = availableMargin - initialRequiredMargin.toInt(); + withdrawableMargin = availableMargin - requiredMargin.toInt(); } /** @@ -132,11 +135,19 @@ contract PerpsAccountModule is IPerpsAccountModule { external view override - returns (uint256 requiredInitialMargin, uint256 requiredMaintenanceMargin) + returns ( + uint256 requiredInitialMargin, + uint256 requiredMaintenanceMargin, + uint256 totalAccumulatedLiquidationRewards, + uint256 maxLiquidationReward + ) { - (requiredInitialMargin, requiredMaintenanceMargin) = PerpsAccount - .load(accountId) - .getAccountRequiredMargins(); + ( + requiredInitialMargin, + requiredMaintenanceMargin, + totalAccumulatedLiquidationRewards, + maxLiquidationReward + ) = PerpsAccount.load(accountId).getAccountRequiredMargins(); } /** diff --git a/markets/perps-market/contracts/storage/AsyncOrder.sol b/markets/perps-market/contracts/storage/AsyncOrder.sol index ddfb1f2601..80fb2aaf53 100644 --- a/markets/perps-market/contracts/storage/AsyncOrder.sol +++ b/markets/perps-market/contracts/storage/AsyncOrder.sol @@ -6,7 +6,9 @@ import {SafeCastI256, SafeCastU256, SafeCastI128} from "@synthetixio/core-contra import {SettlementStrategy} from "./SettlementStrategy.sol"; import {Position} from "./Position.sol"; import {PerpsMarketConfiguration} from "./PerpsMarketConfiguration.sol"; +import {GlobalPerpsMarketConfiguration} from "./GlobalPerpsMarketConfiguration.sol"; import {PerpsMarket} from "./PerpsMarket.sol"; +import {PerpsPrice} from "./PerpsPrice.sol"; import {PerpsAccount} from "./PerpsAccount.sol"; import {MathUtil} from "../utils/MathUtil.sol"; import {OrderFee} from "./OrderFee.sol"; @@ -23,6 +25,7 @@ library AsyncOrder { using SafeCastU256 for uint256; using SafeCastI128 for int128; using PerpsMarketConfiguration for PerpsMarketConfiguration.Data; + using GlobalPerpsMarketConfiguration for GlobalPerpsMarketConfiguration.Data; using PerpsMarket for PerpsMarket.Data; using PerpsAccount for PerpsAccount.Data; using Position for Position.Data; @@ -238,6 +241,8 @@ library AsyncOrder { uint orderFees; uint availableMargin; uint currentLiquidationMargin; + uint accumulatedLiquidationRewards; + uint currentLiquidationReward; int128 newPositionSize; uint newNotionalValue; int currentAvailableMargin; @@ -276,8 +281,14 @@ library AsyncOrder { PerpsAccount.Data storage account = PerpsAccount.load(runtime.accountId); bool isEligible; - (isEligible, runtime.currentAvailableMargin, , runtime.requiredMaintenanceMargin) = account - .isEligibleForLiquidation(); + ( + isEligible, + runtime.currentAvailableMargin, + , + runtime.requiredMaintenanceMargin, + runtime.accumulatedLiquidationRewards, + + ) = account.isEligibleForLiquidation(); if (isEligible) { revert PerpsAccount.AccountLiquidatable(runtime.accountId); @@ -327,25 +338,17 @@ library AsyncOrder { ); runtime.newPositionSize = oldPosition.size + runtime.sizeDelta; - (, , runtime.initialRequiredMargin, , ) = marketConfig.calculateRequiredMargins( - runtime.newPositionSize, - runtime.fillPrice - ); - - // use order price to determine notional value here since we need to subtract - // this amount - (, , , uint256 currentMarketMaintenanceMargin, ) = marketConfig.calculateRequiredMargins( - oldPosition.size, - orderPrice - ); - - // requiredMaintenanceMargin includes the maintenance margin for the current position that's - // being modified, so we subtract the maintenance margin and use the initial required margin runtime.totalRequiredMargin = - runtime.orderFees + - runtime.requiredMaintenanceMargin + - runtime.initialRequiredMargin - - currentMarketMaintenanceMargin; + _getRequiredMarginWithNewPosition( + marketConfig, + runtime.marketId, + oldPosition.size, + runtime.newPositionSize, + runtime.fillPrice, + runtime.requiredMaintenanceMargin, + runtime.accumulatedLiquidationRewards + ) + + runtime.orderFees; if (runtime.currentAvailableMargin < runtime.totalRequiredMargin.toInt()) { revert InsufficientMargin(runtime.currentAvailableMargin, runtime.totalRequiredMargin); @@ -458,4 +461,42 @@ library AsyncOrder { // the fill price is the average of those prices return (priceBefore + priceAfter).toUint().divDecimal(DecimalMath.UNIT * 2); } + + /** + * @notice After the required margins are calculated with the old position, this function replaces the + * old position data with the new position margin requirements and returns them. + */ + function _getRequiredMarginWithNewPosition( + PerpsMarketConfiguration.Data storage marketConfig, + uint128 marketId, + int128 oldPositionSize, + int128 newPositionSize, + uint256 fillPrice, + uint currentTotalMaintenanceMargin, + uint currentTotalLiquidationRewards + ) internal view returns (uint) { + // get initial margin requirement for the new position + (, , uint newRequiredMargin, , uint newLiquidationReward) = marketConfig + .calculateRequiredMargins(newPositionSize, fillPrice); + + // get maintenance margin of old position + (, , , uint256 oldRequiredMargin, uint oldLiquidationReward) = marketConfig + .calculateRequiredMargins(oldPositionSize, PerpsPrice.getCurrentPrice(marketId)); + + // remove the maintenance margin and add the initial margin requirement + // this gets us our total required margin for new position + uint requiredMarginForNewPosition = currentTotalMaintenanceMargin + + newRequiredMargin - + oldRequiredMargin; + + // do same thing for liquidation rewards and compute against global configured min/max liq reward + uint requiredLiquidationRewardMargin = GlobalPerpsMarketConfiguration + .load() + .liquidationReward( + currentTotalLiquidationRewards + newLiquidationReward - oldLiquidationReward + ); + + // this is the required margin for the new position (minus any order fees) + return requiredMarginForNewPosition + requiredLiquidationRewardMargin; + } } diff --git a/markets/perps-market/contracts/storage/PerpsAccount.sol b/markets/perps-market/contracts/storage/PerpsAccount.sol index 0c7bbd9fa2..8185e12954 100644 --- a/markets/perps-market/contracts/storage/PerpsAccount.sol +++ b/markets/perps-market/contracts/storage/PerpsAccount.sol @@ -78,15 +78,22 @@ library PerpsAccount { bool isEligible, int256 availableMargin, uint256 requiredInitialMargin, - uint256 requiredMaintenanceMargin + uint256 requiredMaintenanceMargin, + uint256 accumulatedLiquidationRewards, + uint256 liquidationReward ) { availableMargin = getAvailableMargin(self); if (self.openPositionMarketIds.length() == 0) { - return (false, availableMargin, 0, 0); + return (false, availableMargin, 0, 0, 0, 0); } - (requiredInitialMargin, requiredMaintenanceMargin) = getAccountRequiredMargins(self); - isEligible = requiredMaintenanceMargin.toInt() > availableMargin; + ( + requiredInitialMargin, + requiredMaintenanceMargin, + accumulatedLiquidationRewards, + liquidationReward + ) = getAccountRequiredMargins(self); + isEligible = (requiredMaintenanceMargin + liquidationReward).toInt() > availableMargin; } function flagForLiquidation(Data storage self) internal { @@ -139,15 +146,18 @@ library PerpsAccount { bool isEligible, int256 availableMargin, uint256 initialRequiredMargin, - + , + , + uint256 liquidationReward ) = isEligibleForLiquidation(self); if (isEligible) { revert AccountLiquidatable(self.id); } + uint256 requiredMargin = initialRequiredMargin + liquidationReward; // availableMargin can be assumed to be positive since we check for isEligible for liquidation prior - availableWithdrawableCollateralUsd = availableMargin.toUint() - initialRequiredMargin; + availableWithdrawableCollateralUsd = availableMargin.toUint() - requiredMargin; if (amountToWithdraw > availableWithdrawableCollateralUsd) { revert InsufficientCollateralAvailableForWithdraw( @@ -212,9 +222,17 @@ library PerpsAccount { */ function getAccountRequiredMargins( Data storage self - ) internal view returns (uint initialMargin, uint maintenanceMargin) { + ) + internal + view + returns ( + uint initialMargin, + uint maintenanceMargin, + uint accumulatedLiquidationRewards, + uint liquidationReward + ) + { // use separate accounting for liquidation rewards so we can compare against global min/max liquidation reward values - uint256 accumulatedLiquidationRewards; for (uint i = 1; i <= self.openPositionMarketIds.length(); i++) { uint128 marketId = self.openPositionMarketIds.valueAt(i).to128(); Position.Data storage position = PerpsMarket.load(marketId).positions[self.id]; @@ -243,8 +261,10 @@ library PerpsAccount { ); return ( - initialMargin + possibleLiquidationReward, - maintenanceMargin + possibleLiquidationReward + initialMargin, + maintenanceMargin, + accumulatedLiquidationRewards, + possibleLiquidationReward ); } diff --git a/markets/perps-market/test/integration/Orders/Order.marginValidation.test.ts b/markets/perps-market/test/integration/Orders/Order.marginValidation.test.ts new file mode 100644 index 0000000000..f615031dcb --- /dev/null +++ b/markets/perps-market/test/integration/Orders/Order.marginValidation.test.ts @@ -0,0 +1,291 @@ +import assertBn from '@synthetixio/core-utils/utils/assertions/assert-bignumber'; +import assertRevert from '@synthetixio/core-utils/utils/assertions/assert-revert'; +import { bn, bootstrapMarkets } from '../bootstrap'; +import { + calculateFillPrice, + getMaxLiquidationReward, + openPosition, + requiredMargins, +} from '../helpers'; +import { wei } from '@synthetixio/wei'; +import { ethers } from 'ethers'; + +describe('Orders - margin validation', () => { + const liqParams = { + btc: { + imRatio: wei(0.02), + minIm: wei(0.01), + mmScalar: wei(0.5), + liqRatio: wei(0.0075), + }, + eth: { + imRatio: wei(0.02), + minIm: wei(0.01), + mmScalar: wei(0.5), + liqRatio: wei(0.01), + }, + }; + + const { systems, provider, trader1, perpsMarkets, keeper } = bootstrapMarkets({ + synthMarkets: [], + liquidationGuards: { + minLiquidationReward: bn(100), + maxLiquidationReward: bn(500), + }, + perpsMarkets: [ + { + requestedMarketId: 50, + name: 'Bitcoin', + token: 'BTC', + price: bn(10_000), + fundingParams: { skewScale: bn(1000), maxFundingVelocity: bn(0) }, + liquidationParams: { + initialMarginFraction: liqParams.btc.imRatio.toBN(), + minimumInitialMarginRatio: liqParams.btc.minIm.toBN(), + maintenanceMarginScalar: liqParams.btc.mmScalar.toBN(), + maxLiquidationLimitAccumulationMultiplier: bn(1), + liquidationRewardRatio: liqParams.btc.liqRatio.toBN(), + maxSecondsInLiquidationWindow: bn(10), + minimumPositionMargin: bn(0), + }, + settlementStrategy: { + settlementReward: bn(0), + }, + }, + { + requestedMarketId: 51, + name: 'Ether', + token: 'ETH', + price: bn(2000), + fundingParams: { skewScale: bn(10_000), maxFundingVelocity: bn(0) }, + liquidationParams: { + initialMarginFraction: liqParams.eth.imRatio.toBN(), + minimumInitialMarginRatio: liqParams.eth.minIm.toBN(), + maintenanceMarginScalar: liqParams.eth.mmScalar.toBN(), + maxLiquidationLimitAccumulationMultiplier: bn(1), + liquidationRewardRatio: liqParams.eth.liqRatio.toBN(), + maxSecondsInLiquidationWindow: bn(10), + minimumPositionMargin: bn(0), + }, + settlementStrategy: { + settlementReward: bn(0), + }, + }, + ], + traderAccountIds: [2], + }); + + before('add margin to account', async () => { + await systems().PerpsMarket.connect(trader1()).modifyCollateral(2, 0, bn(100)); + }); + + describe('openPosition 1 failure', () => { + let orderFees: ethers.BigNumber; + before('get order fees', async () => { + orderFees = await systems().PerpsMarket.computeOrderFees(51, 3); + }); + + it('reverts if not enough margin', async () => { + const { initialMargin, liquidationMargin } = requiredMargins( + { + initialMarginRatio: liqParams.eth.imRatio, + minimumInitialMarginRatio: liqParams.eth.minIm, + maintenanceMarginScalar: liqParams.eth.mmScalar, + liquidationRewardRatio: liqParams.eth.liqRatio, + }, + wei(3), + calculateFillPrice(wei(0), wei(10_000), wei(3), wei(2000)), + wei(10_000) + ); + + await assertRevert( + systems() + .PerpsMarket.connect(trader1()) + .commitOrder({ + marketId: 51, + accountId: 2, + sizeDelta: bn(3), + settlementStrategyId: perpsMarkets()[1].strategyId(), + acceptablePrice: bn(3000), + referrer: ethers.constants.AddressZero, + trackingCode: ethers.constants.HashZero, + }), + `InsufficientMargin("${bn(100)}", "${initialMargin + .add(getMaxLiquidationReward(liquidationMargin, wei(100), wei(500))) + .add(orderFees) + .toString(18, true)}")` + ); + }); + }); + + describe('openPosition 1 success', () => { + before('add more margin', async () => { + await systems().PerpsMarket.connect(trader1()).modifyCollateral(2, 0, bn(100)); + }); + + before('open position', async () => { + await openPosition({ + systems, + provider, + trader: trader1(), + accountId: 2, + keeper: keeper(), + marketId: perpsMarkets()[1].marketId(), + sizeDelta: bn(3), + settlementStrategyId: perpsMarkets()[1].strategyId(), + price: bn(2000), + }); + }); + + it('opens position', async () => { + const [, , positionSize] = await systems().PerpsMarket.getOpenPosition( + 2, + perpsMarkets()[1].marketId() + ); + assertBn.equal(positionSize, bn(3)); + }); + }); + + describe('openPosition 2 failure', () => { + let orderFees: ethers.BigNumber; + before('get order fees', async () => { + orderFees = await systems().PerpsMarket.computeOrderFees(50, 5); + }); + + it('reverts if not enough margin', async () => { + // previous order margins + const { maintenanceMargin: ethMaintMargin, liquidationMargin: ethLiqMargin } = + requiredMargins( + { + initialMarginRatio: liqParams.eth.imRatio, + minimumInitialMarginRatio: liqParams.eth.minIm, + maintenanceMarginScalar: liqParams.eth.mmScalar, + liquidationRewardRatio: liqParams.eth.liqRatio, + }, + wei(3), + wei(2000), + wei(10_000) + ); + + const { initialMargin: btcInitialMargin, liquidationMargin: btcLiqMargin } = requiredMargins( + { + initialMarginRatio: liqParams.btc.imRatio, + minimumInitialMarginRatio: liqParams.btc.minIm, + maintenanceMarginScalar: liqParams.btc.mmScalar, + liquidationRewardRatio: liqParams.btc.liqRatio, + }, + wei(5), + calculateFillPrice(wei(0), wei(1000), wei(5), wei(10_000)), + wei(1000) + ); + + const liqReward = getMaxLiquidationReward(ethLiqMargin.add(btcLiqMargin), wei(100), wei(500)); + + const totalRequiredMargin = ethMaintMargin + .add(btcInitialMargin) + .add(liqReward) + .add(orderFees); + + await assertRevert( + systems() + .PerpsMarket.connect(trader1()) + .commitOrder({ + marketId: 50, + accountId: 2, + sizeDelta: bn(5), + settlementStrategyId: perpsMarkets()[0].strategyId(), + acceptablePrice: bn(11000), + referrer: ethers.constants.AddressZero, + trackingCode: ethers.constants.HashZero, + }), + `InsufficientMargin("${await systems().PerpsMarket.getAvailableMargin( + 2 + )}", "${totalRequiredMargin.toString(18, true)}")` + ); + }); + }); + + describe('openPosition 2 success', () => { + before('add more margin', async () => { + await systems().PerpsMarket.connect(trader1()).modifyCollateral(2, 0, bn(1100)); + }); + + before('open position', async () => { + await openPosition({ + systems, + provider, + trader: trader1(), + accountId: 2, + keeper: keeper(), + marketId: perpsMarkets()[0].marketId(), + sizeDelta: bn(5), + settlementStrategyId: perpsMarkets()[0].strategyId(), + price: bn(10_000), + }); + }); + + it('opens position', async () => { + const [, , positionSize] = await systems().PerpsMarket.getOpenPosition(2, 50); + assertBn.equal(positionSize, bn(5)); + }); + }); + + describe('modify position', () => { + let orderFees: ethers.BigNumber; + before('get order fees', async () => { + orderFees = await systems().PerpsMarket.computeOrderFees(50, 5); + }); + + it('reverts if not enough margin', async () => { + // previous order margins + const { maintenanceMargin: ethMaintMargin, liquidationMargin: ethLiqMargin } = + requiredMargins( + { + initialMarginRatio: liqParams.eth.imRatio, + minimumInitialMarginRatio: liqParams.eth.minIm, + maintenanceMarginScalar: liqParams.eth.mmScalar, + liquidationRewardRatio: liqParams.eth.liqRatio, + }, + wei(3), + wei(2000), + wei(10_000) + ); + + const { initialMargin: btcInitialMargin, liquidationMargin: btcLiqMargin } = requiredMargins( + { + initialMarginRatio: liqParams.btc.imRatio, + minimumInitialMarginRatio: liqParams.btc.minIm, + maintenanceMarginScalar: liqParams.btc.mmScalar, + liquidationRewardRatio: liqParams.btc.liqRatio, + }, + wei(10), + calculateFillPrice(wei(5), wei(1000), wei(5), wei(10_000)), + wei(1000) + ); + + const liqReward = getMaxLiquidationReward(ethLiqMargin.add(btcLiqMargin), wei(100), wei(500)); + + const totalRequiredMargin = ethMaintMargin + .add(btcInitialMargin) + .add(liqReward) + .add(orderFees); + + await assertRevert( + systems() + .PerpsMarket.connect(trader1()) + .commitOrder({ + marketId: 50, + accountId: 2, + sizeDelta: bn(5), + settlementStrategyId: perpsMarkets()[0].strategyId(), + acceptablePrice: bn(11000), + referrer: ethers.constants.AddressZero, + trackingCode: ethers.constants.HashZero, + }), + `InsufficientMargin("${await systems().PerpsMarket.getAvailableMargin( + 2 + )}", "${totalRequiredMargin.toString(18, true)}")` + ); + }); + }); +}); diff --git a/markets/perps-market/test/integration/helpers/index.ts b/markets/perps-market/test/integration/helpers/index.ts index 6abdbe6026..f3954a71b3 100644 --- a/markets/perps-market/test/integration/helpers/index.ts +++ b/markets/perps-market/test/integration/helpers/index.ts @@ -3,3 +3,4 @@ export * from './collateralHelper'; export * from './openPosition'; export * from './fillPrice'; export * from './computeFees'; +export * from './requiredMargins'; diff --git a/markets/perps-market/test/integration/helpers/requiredMargins.ts b/markets/perps-market/test/integration/helpers/requiredMargins.ts new file mode 100644 index 0000000000..a5bd21216a --- /dev/null +++ b/markets/perps-market/test/integration/helpers/requiredMargins.ts @@ -0,0 +1,28 @@ +import Wei from '@synthetixio/wei'; + +type Config = { + initialMarginRatio: Wei; + minimumInitialMarginRatio: Wei; + maintenanceMarginScalar: Wei; + liquidationRewardRatio: Wei; +}; + +export const requiredMargins = (config: Config, size: Wei, price: Wei, skewScale: Wei) => { + const impactOnSkew = size.div(skewScale); + const initialMarginRatio = impactOnSkew + .mul(config.initialMarginRatio) + .add(config.minimumInitialMarginRatio); + + const maintenanceMarginRatio = initialMarginRatio.mul(config.maintenanceMarginScalar); + const notional = size.mul(price); + + return { + initialMargin: notional.mul(initialMarginRatio), + maintenanceMargin: notional.mul(maintenanceMarginRatio), + liquidationMargin: notional.mul(config.liquidationRewardRatio), + }; +}; + +export const getMaxLiquidationReward = (reward: Wei, min: Wei, max: Wei) => { + return Wei.min(Wei.max(reward, min), max); +}; From c1d36822ac6d0e34a61f99cb19c07c420a1c6dec Mon Sep 17 00:00:00 2001 From: Peiman Date: Tue, 8 Aug 2023 23:49:49 +0330 Subject: [PATCH 38/63] fix: failing tests --- protocol/synthetix/test/integration/bootstrap.ts | 9 +++++++++ .../modules/core/PoolModuleFundAdmin.test.ts | 2 +- .../integration/modules/core/VaultModule.test.ts | 12 +++++++++++- 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/protocol/synthetix/test/integration/bootstrap.ts b/protocol/synthetix/test/integration/bootstrap.ts index f240351779..f8e71712a9 100644 --- a/protocol/synthetix/test/integration/bootstrap.ts +++ b/protocol/synthetix/test/integration/bootstrap.ts @@ -107,6 +107,15 @@ export function bootstrapWithMockMarketAndPool() { maxDebtShareValueD18: ethers.utils.parseEther('1'), }, ]); + + await r + .systems() + .Core.connect(owner) + .setPoolCollateralConfiguration(r.poolId, r.collateralAddress(), { + maxDepositD18: bn(1000000000), + collateralTypeDisabled: false, + issuanceRatioD18: bn(1), + }); }); const restore = snapshotCheckpoint(r.provider); diff --git a/protocol/synthetix/test/integration/modules/core/PoolModuleFundAdmin.test.ts b/protocol/synthetix/test/integration/modules/core/PoolModuleFundAdmin.test.ts index 114d224598..bec3006d58 100644 --- a/protocol/synthetix/test/integration/modules/core/PoolModuleFundAdmin.test.ts +++ b/protocol/synthetix/test/integration/modules/core/PoolModuleFundAdmin.test.ts @@ -731,7 +731,7 @@ describe('PoolModule Admin', function () { .Core.connect(user1) .setPoolCollateralConfiguration(thirdPoolId, collateralAddress(), { maxDepositD18: bn(10), - collateralTypeDisabled: false, + collateralTypeDisabled: true, 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 286f49b1ba..408f26b4ef 100644 --- a/protocol/synthetix/test/integration/modules/core/VaultModule.test.ts +++ b/protocol/synthetix/test/integration/modules/core/VaultModule.test.ts @@ -366,7 +366,7 @@ describe('VaultModule', function () { await systems() .Core.connect(user1) .setPoolCollateralConfiguration(fakeVaultId, collateralAddress(), { - maxDepositD18: bn(10), + maxDepositD18: bn(1000000), collateralTypeDisabled: false, issuanceRatioD18: bn(0), }); @@ -449,6 +449,16 @@ describe('VaultModule', function () { describe('second user delegates', async () => { const user2AccountId = 283847; + before('set pool limit', async () => { + await systems() + .Core.connect(owner) + .setPoolCollateralConfiguration(poolId, collateralAddress(), { + maxDepositD18: depositAmount.mul(10), + collateralTypeDisabled: false, + issuanceRatioD18: bn(0), + }); + }); + before('second user delegates and mints', async () => { // user1 has extra collateral available await collateralContract() From 02fd2965d7e0893236b1a40362d75c0369c4b254 Mon Sep 17 00:00:00 2001 From: max <39312833+fritzschoff@users.noreply.github.com> Date: Wed, 9 Aug 2023 15:58:02 +0200 Subject: [PATCH 39/63] SIP-332 (#1743) * started sip-332 * updated IssueUSDModule * fixing tests * defined var * fixed all tests * removed comment * fixing tests * removing unused constant * building repo * fixing test * removed only * ran build in the root --------- Co-authored-by: butternutsquash --- markets/perps-market/storage.dump.sol | 25 ++++++++++----- .../modules/core/CollateralModule.sol | 1 - .../contracts/modules/core/IssueUSDModule.sol | 31 ++++++++++++++----- protocol/synthetix/storage.dump.sol | 8 ++++- protocol/synthetix/test/common/stakers.ts | 13 ++++++-- .../modules/core/CcipReceiverModule.test.ts | 2 +- .../CollateralModule.locks.test.ts | 11 +++---- .../modules/core/CrossChainUSDModule.test.ts | 17 +++++----- .../modules/core/IssueUSDModule.test.ts | 16 ++++++++++ .../modules/core/LiquidationModule.test.ts | 21 ++++++++++--- .../modules/core/MarketManagerModule.test.ts | 6 ++++ .../modules/core/PoolModuleFundAdmin.test.ts | 3 ++ .../modules/core/USDTokenModule.test.ts | 3 ++ .../modules/core/VaultModule.test.ts | 4 +++ 14 files changed, 120 insertions(+), 41 deletions(-) diff --git a/markets/perps-market/storage.dump.sol b/markets/perps-market/storage.dump.sol index 5579446c2d..0a8e70c40b 100644 --- a/markets/perps-market/storage.dump.sol +++ b/markets/perps-market/storage.dump.sol @@ -426,7 +426,12 @@ interface IAsyncOrderSettlementModule { uint256 pnlUint; uint256 amountToDeduct; uint256 settlementReward; - PerpsMarketFactory.Data factory; + uint256 fillPrice; + uint256 totalFees; + uint256 referralFees; + uint256 feeCollectorFees; + Position.Data newPosition; + PerpsMarket.MarketUpdateData updateData; } } @@ -471,13 +476,8 @@ contract PerpsMarketFactoryModule { // @custom:artifact contracts/storage/AsyncOrder.sol:AsyncOrder library AsyncOrder { struct Data { - uint128 accountId; - uint128 marketId; - int128 sizeDelta; - uint128 settlementStrategyId; uint256 settlementTime; - uint256 acceptablePrice; - bytes32 trackingCode; + OrderCommitmentRequest request; } struct OrderCommitmentRequest { uint128 marketId; @@ -486,12 +486,18 @@ library AsyncOrder { uint128 settlementStrategyId; uint256 acceptablePrice; bytes32 trackingCode; + address referrer; } struct SimulateDataRuntime { + int128 sizeDelta; + uint128 accountId; + uint128 marketId; uint fillPrice; uint orderFees; uint availableMargin; uint currentLiquidationMargin; + uint accumulatedLiquidationRewards; + uint currentLiquidationReward; int128 newPositionSize; uint newNotionalValue; int currentAvailableMargin; @@ -530,6 +536,8 @@ library GlobalPerpsMarket { library GlobalPerpsMarketConfiguration { bytes32 private constant _SLOT_GLOBAL_PERPS_MARKET_CONFIGURATION = keccak256(abi.encode("io.synthetix.perps-market.GlobalPerpsMarketConfiguration")); struct Data { + address feeCollector; + mapping(address => uint256) referrerShare; mapping(uint128 => uint) maxCollateralAmounts; uint128[] synthDeductionPriority; uint minLiquidationRewardUsd; @@ -608,12 +616,13 @@ library PerpsMarketConfiguration { uint256 maxFundingVelocity; uint256 skewScale; uint256 initialMarginRatioD18; - uint256 maintenanceMarginRatioD18; + uint256 maintenanceMarginScalarD18; uint256 lockedOiRatioD18; uint256 maxLiquidationLimitAccumulationMultiplier; uint256 maxSecondsInLiquidationWindow; uint256 liquidationRewardRatioD18; uint256 minimumPositionMargin; + uint256 minimumInitialMarginRatioD18; } function load(uint128 marketId) internal pure returns (Data storage store) { bytes32 s = keccak256(abi.encode("io.synthetix.perps-market.PerpsMarketConfiguration", marketId)); diff --git a/protocol/synthetix/contracts/modules/core/CollateralModule.sol b/protocol/synthetix/contracts/modules/core/CollateralModule.sol index feb5df58e0..70f976fc03 100644 --- a/protocol/synthetix/contracts/modules/core/CollateralModule.sol +++ b/protocol/synthetix/contracts/modules/core/CollateralModule.sol @@ -28,7 +28,6 @@ contract CollateralModule is ICollateralModule { bytes32 private constant _DEPOSIT_FEATURE_FLAG = "deposit"; bytes32 private constant _WITHDRAW_FEATURE_FLAG = "withdraw"; - bytes32 private constant _CONFIG_TIMEOUT_WITHDRAW = "accountTimeoutWithdraw"; /** diff --git a/protocol/synthetix/contracts/modules/core/IssueUSDModule.sol b/protocol/synthetix/contracts/modules/core/IssueUSDModule.sol index 0aa66bd576..abc2967a7c 100644 --- a/protocol/synthetix/contracts/modules/core/IssueUSDModule.sol +++ b/protocol/synthetix/contracts/modules/core/IssueUSDModule.sol @@ -1,18 +1,18 @@ //SPDX-License-Identifier: MIT pragma solidity >=0.8.11 <0.9.0; -import "../../interfaces/IIssueUSDModule.sol"; - import "@synthetixio/core-contracts/contracts/utils/SafeCast.sol"; +import "@synthetixio/core-modules/contracts/storage/FeatureFlag.sol"; import "@synthetixio/core-modules/contracts/storage/AssociatedSystem.sol"; +import "../../interfaces/IIssueUSDModule.sol"; + import "../../storage/Account.sol"; +import "../../storage/Collateral.sol"; import "../../storage/CollateralConfiguration.sol"; import "../../storage/Config.sol"; -import "@synthetixio/core-modules/contracts/storage/FeatureFlag.sol"; - /** * @title Module for the minting and burning of stablecoins. * @dev See IIssueUSDModule. @@ -23,6 +23,7 @@ contract IssueUSDModule is IIssueUSDModule { using AssociatedSystem for AssociatedSystem.Data; using Pool for Pool.Data; using CollateralConfiguration for CollateralConfiguration.Data; + using Collateral for Collateral.Data; using Vault for Vault.Data; using VaultEpoch for VaultEpoch.Data; using Distribution for Distribution.Data; @@ -37,10 +38,8 @@ contract IssueUSDModule is IIssueUSDModule { using SafeCastI256 for int256; bytes32 private constant _USD_TOKEN = "USDToken"; - bytes32 private constant _MINT_FEATURE_FLAG = "mintUsd"; bytes32 private constant _BURN_FEATURE_FLAG = "burnUsd"; - bytes32 private constant _CONFIG_MINT_FEE_RATIO = "mintUsd_feeRatio"; bytes32 private constant _CONFIG_BURN_FEE_RATIO = "burnUsd_feeRatio"; bytes32 private constant _CONFIG_MINT_FEE_ADDRESS = "mintUsd_feeAddress"; @@ -56,7 +55,11 @@ contract IssueUSDModule is IIssueUSDModule { uint256 amount ) external override { FeatureFlag.ensureAccessToFeature(_MINT_FEATURE_FLAG); - Account.loadAccountAndValidatePermission(accountId, AccountRBAC._MINT_PERMISSION); + + Account.Data storage account = Account.loadAccountAndValidatePermission( + accountId, + AccountRBAC._MINT_PERMISSION + ); // disabled collateralType cannot be used for minting CollateralConfiguration.collateralEnabled(collateralType); @@ -97,8 +100,14 @@ contract IssueUSDModule is IIssueUSDModule { // Decrease the credit available in the vault pool.recalculateVaultCollateral(collateralType); + AssociatedSystem.Data storage usdToken = AssociatedSystem.load(_USD_TOKEN); + // Mint stablecoins to the sender - AssociatedSystem.load(_USD_TOKEN).asToken().mint(msg.sender, amount); + usdToken.asToken().mint(address(this), amount); + + account.collaterals[usdToken.getAddress()].increaseAvailableCollateral( + CollateralConfiguration.load(usdToken.getAddress()).convertTokenToSystemAmount(amount) + ); if (feeAmount > 0 && feeAddress != address(0)) { AssociatedSystem.load(_USD_TOKEN).asToken().mint(feeAddress, feeAmount); @@ -121,6 +130,8 @@ contract IssueUSDModule is IIssueUSDModule { FeatureFlag.ensureAccessToFeature(_BURN_FEATURE_FLAG); Pool.Data storage pool = Pool.load(poolId); + Account.Data storage account = Account.load(accountId); + // Retrieve current position debt int256 debt = pool.updateAccountDebt(collateralType, accountId); @@ -144,6 +155,10 @@ contract IssueUSDModule is IIssueUSDModule { // Burn the stablecoins AssociatedSystem.load(_USD_TOKEN).asToken().burn(msg.sender, amount); + account.collaterals[collateralType].increaseAvailableCollateral( + CollateralConfiguration.load(collateralType).convertTokenToSystemAmount(amount) + ); + if (feeAmount > 0 && feeAddress != address(0)) { AssociatedSystem.load(_USD_TOKEN).asToken().mint(feeAddress, feeAmount); diff --git a/protocol/synthetix/storage.dump.sol b/protocol/synthetix/storage.dump.sol index a0061373fe..6e27eedc82 100644 --- a/protocol/synthetix/storage.dump.sol +++ b/protocol/synthetix/storage.dump.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.4; +pragma solidity >=0.4.22<0.9.0; // @custom:artifact @synthetixio/core-contracts/contracts/ownership/OwnableStorage.sol:OwnableStorage library OwnableStorage { @@ -268,6 +268,7 @@ contract IssueUSDModule { bytes32 private constant _CONFIG_BURN_FEE_RATIO = "burnUsd_feeRatio"; bytes32 private constant _CONFIG_MINT_FEE_ADDRESS = "mintUsd_feeAddress"; bytes32 private constant _CONFIG_BURN_FEE_ADDRESS = "burnUsd_feeAddress"; + bytes32 private constant _CONFIG_TIMEOUT_BURN = "burnUsd_toAccount"; } // @custom:artifact contracts/modules/core/LiquidationModule.sol:LiquidationModule @@ -667,3 +668,8 @@ library CcipClient { bool strict; } } + +// @custom:artifact hardhat/console.sol:console +library console { + address internal constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67); +} diff --git a/protocol/synthetix/test/common/stakers.ts b/protocol/synthetix/test/common/stakers.ts index 61b5bd07d6..e9ef9d3c68 100644 --- a/protocol/synthetix/test/common/stakers.ts +++ b/protocol/synthetix/test/common/stakers.ts @@ -36,12 +36,21 @@ export function bootstrapStakers( await systems() .Core.connect(staker1) .mintUsd(1000, 2, collateralAddress, delegateAmount.mul(200)); + await systems() + .Core.connect(staker1) + .withdraw(1000, await systems().Core.getUsdToken(), delegateAmount.mul(200)); await systems() .Core.connect(staker2) .mintUsd(1001, 2, collateralAddress, delegateAmount.mul(200)); + await systems() + .Core.connect(staker2) + .withdraw(1001, await systems().Core.getUsdToken(), delegateAmount.mul(200)); await systems() .Core.connect(staker3) .mintUsd(1002, 2, collateralAddress, delegateAmount.mul(200)); + await systems() + .Core.connect(staker3) + .withdraw(1002, await systems().Core.getUsdToken(), delegateAmount.mul(200)); }); } @@ -59,10 +68,10 @@ export const stake = async ( await Core.connect(user)['createAccount(uint128)'](accountId); // approve - await CollateralMock.connect(user).approve(Core.address, delegateAmount.mul(10)); + await CollateralMock.connect(user).approve(Core.address, delegateAmount.mul(300)); // stake collateral - await Core.connect(user).deposit(accountId, CollateralMock.address, delegateAmount.mul(10)); + await Core.connect(user).deposit(accountId, CollateralMock.address, delegateAmount.mul(300)); // invest in the pool await Core.connect(user).delegateCollateral( diff --git a/protocol/synthetix/test/integration/modules/core/CcipReceiverModule.test.ts b/protocol/synthetix/test/integration/modules/core/CcipReceiverModule.test.ts index 02c4fa9486..edaf89d2f8 100644 --- a/protocol/synthetix/test/integration/modules/core/CcipReceiverModule.test.ts +++ b/protocol/synthetix/test/integration/modules/core/CcipReceiverModule.test.ts @@ -36,7 +36,7 @@ describe('CcipReceiverModule', function () { .Core.connect(staker()) .mintUsd(accountId, poolId, collateralAddress(), twoHundredUSD); - await systems().USD.connect(staker()).transfer(systems().Core.address, fiftyUSD); + await systems().Core.connect(staker()).withdraw(accountId, collateralAddress(), fiftyUSD); }); before('record balances', async () => { diff --git a/protocol/synthetix/test/integration/modules/core/CollateralModule/CollateralModule.locks.test.ts b/protocol/synthetix/test/integration/modules/core/CollateralModule/CollateralModule.locks.test.ts index de0007e3f3..87bea5a6d3 100644 --- a/protocol/synthetix/test/integration/modules/core/CollateralModule/CollateralModule.locks.test.ts +++ b/protocol/synthetix/test/integration/modules/core/CollateralModule/CollateralModule.locks.test.ts @@ -53,19 +53,16 @@ describe('CollateralModule', function () { 0, // 0 is invalid for amount to lock 1234123412341 ), - 'InvalidParameter("amount"', + 'InvalidParameter("amount", "must be nonzero")', systems().Core ); }); it('fails when insufficient collateral in account to lock', async () => { await assertRevert( - systems().Core.connect(user1).createLock( - 1, - collateralAddress(), - depositAmount.mul(10).add(1), - 1234123412341 // timestamp is definitely in the past - ), + systems() + .Core.connect(user1) + .createLock(1, collateralAddress(), depositAmount.mul(1000).add(1), 1234123412341), 'InsufficientAccountCollateral(', systems().Core ); diff --git a/protocol/synthetix/test/integration/modules/core/CrossChainUSDModule.test.ts b/protocol/synthetix/test/integration/modules/core/CrossChainUSDModule.test.ts index 30bdf21762..17abd4b2da 100644 --- a/protocol/synthetix/test/integration/modules/core/CrossChainUSDModule.test.ts +++ b/protocol/synthetix/test/integration/modules/core/CrossChainUSDModule.test.ts @@ -32,19 +32,15 @@ describe('CrossChainUSDModule', function () { .configureChainlinkCrossChain(CcipRouterMock.address, ethers.constants.AddressZero); }); - before('get some snxUSD', async () => { + before('mint some sUSD', async () => { await systems() .Core.connect(staker()) .mintUsd(accountId, poolId, collateralAddress(), oneHundredUSD); - - // await systems() - // .Core.connect(staker()) - // .withdraw(accountId, systems().USD.address, oneHundredUSD); }); before('record balances', async () => { stakerBalanceBefore = await systems().USD.connect(staker()).balanceOf(stakerAddress); - proxyBalanceBefore = await systems().USD.connect(staker()).balanceOf(systems().Core.address); + proxyBalanceBefore = await systems().USD.balanceOf(systems().Core.address); }); describe('transferCrossChain()', () => { @@ -63,7 +59,7 @@ describe('CrossChainUSDModule', function () { ); }); - it('reverts if the sender did not set enough allownce', async () => { + it('reverts if the sender did not set enough allowance', async () => { const allowance = await systems() .USD.connect(staker()) .allowance(stakerAddress, systems().Core.address); @@ -93,6 +89,9 @@ describe('CrossChainUSDModule', function () { let transferCrossChainTxn: ethers.providers.TransactionResponse; before('invokes transferCrossChain', async () => { + await systems() + .Core.connect(staker()) + .withdraw(accountId, await systems().Core.getUsdToken(), fiftyUSD); transferCrossChainTxn = await systems() .Core.connect(staker()) .transferCrossChain(1, fiftyUSD); @@ -102,12 +101,12 @@ describe('CrossChainUSDModule', function () { const usdBalanceAfter = await systems() .USD.connect(owner()) .balanceOf(systems().Core.address); - assertBn.equal(usdBalanceAfter, proxyBalanceBefore.add(fiftyUSD)); + assertBn.equal(usdBalanceAfter, proxyBalanceBefore); }); it('should decrease the stakers balance by the expected amount', async () => { const usdBalanceAfter = await systems().USD.connect(staker()).balanceOf(stakerAddress); - assertBn.equal(usdBalanceAfter, stakerBalanceBefore.sub(fiftyUSD)); + assertBn.equal(usdBalanceAfter, 0); }); it('emits correct event with the expected values', async () => { diff --git a/protocol/synthetix/test/integration/modules/core/IssueUSDModule.test.ts b/protocol/synthetix/test/integration/modules/core/IssueUSDModule.test.ts index f1bfac6a84..6e0f12da87 100644 --- a/protocol/synthetix/test/integration/modules/core/IssueUSDModule.test.ts +++ b/protocol/synthetix/test/integration/modules/core/IssueUSDModule.test.ts @@ -145,6 +145,9 @@ describe('IssueUSDModule', function () { collateralAddress(), depositAmount.div(10) // should be enough ); + await systems() + .Core.connect(user1) + .withdraw(accountId, await systems().Core.getUsdToken(), depositAmount.div(10)); }); it( @@ -174,6 +177,10 @@ describe('IssueUSDModule', function () { collateralAddress(), depositAmount.div(10) // should be enough ); + + await systems() + .Core.connect(user1) + .withdraw(accountId, await systems().Core.getUsdToken(), depositAmount.div(10)); }); it( @@ -216,6 +223,9 @@ describe('IssueUSDModule', function () { collateralAddress(), depositAmount.div(10) // should be enough ); + await systems() + .Core.connect(user1) + .withdraw(accountId, await systems().Core.getUsdToken(), depositAmount.div(10)); }); it( @@ -257,6 +267,9 @@ describe('IssueUSDModule', function () { await systems() .Core.connect(user1) .mintUsd(accountId, poolId, collateralAddress(), depositAmount.div(10)); + await systems() + .Core.connect(user1) + .withdraw(accountId, await systems().Core.getUsdToken(), depositAmount.div(10)); }); const restoreBurn = snapshotCheckpoint(provider); @@ -366,6 +379,9 @@ describe('IssueUSDModule', function () { before('account partial burn debt', async () => { // in order to burn all with the fee we need a bit more + await systems() + .Core.connect(user1) + .withdraw(accountId, await systems().Core.getUsdToken(), depositAmount.div(1000)); tx = await systems() .Core.connect(user1) .burnUsd(accountId, poolId, collateralAddress(), depositAmount); // pay off everything diff --git a/protocol/synthetix/test/integration/modules/core/LiquidationModule.test.ts b/protocol/synthetix/test/integration/modules/core/LiquidationModule.test.ts index 3e176446f9..f48db0444c 100644 --- a/protocol/synthetix/test/integration/modules/core/LiquidationModule.test.ts +++ b/protocol/synthetix/test/integration/modules/core/LiquidationModule.test.ts @@ -54,6 +54,10 @@ describe('LiquidationModule', function () { await systems() .Core.connect(user1) .mintUsd(accountId, poolId, collateralAddress(), debtAmount.div(10)); + + await systems() + .Core.connect(user1) + .withdraw(accountId, await systems().Core.getUsdToken(), debtAmount.div(10)); }); before('going into debt', async () => { @@ -226,6 +230,10 @@ describe('LiquidationModule', function () { await systems() .Core.connect(user1) .mintUsd(accountId, poolId, collateralAddress(), debtAmount.div(10)); + + await systems() + .Core.connect(user1) + .withdraw(accountId, await systems().Core.getUsdToken(), debtAmount.div(10)); }); before('going into debt', async () => { @@ -268,8 +276,6 @@ describe('LiquidationModule', function () { await systems() .Core.connect(user2) .deposit(liquidatorAccountId, collateralAddress(), depositAmount.mul(50)); - - // use the zero pool to get minted USD await systems() .Core.connect(user2) .delegateCollateral( @@ -279,10 +285,17 @@ describe('LiquidationModule', function () { depositAmount.mul(50), ethers.utils.parseEther('1') ); - await systems() .Core.connect(user2) .mintUsd(liquidatorAccountId, 0, collateralAddress(), liquidatorAccountStartingBalance); + + await systems() + .Core.connect(user2) + .withdraw( + liquidatorAccountId, + await systems().Core.getUsdToken(), + liquidatorAccountStartingBalance + ); }); before('record collateral ratio', async () => { @@ -342,7 +355,7 @@ describe('LiquidationModule', function () { ); }); - describe('succesful full liquidation', () => { + describe('successful full liquidation', () => { let txn: ethers.providers.TransactionResponse; before('liquidate', async () => { diff --git a/protocol/synthetix/test/integration/modules/core/MarketManagerModule.test.ts b/protocol/synthetix/test/integration/modules/core/MarketManagerModule.test.ts index 95da5b8a0a..2a9b338958 100644 --- a/protocol/synthetix/test/integration/modules/core/MarketManagerModule.test.ts +++ b/protocol/synthetix/test/integration/modules/core/MarketManagerModule.test.ts @@ -93,6 +93,9 @@ describe('MarketManagerModule', function () { before('acquire USD', async () => { await systems().Core.connect(user1).mintUsd(accountId, 0, collateralAddress(), One); + await systems() + .Core.connect(user1) + .withdraw(accountId, await systems().Core.getUsdToken(), One); }); it('should not work if user has not approved', async () => { @@ -224,6 +227,9 @@ describe('MarketManagerModule', function () { describe('deposit into the pool', async () => { before('mint USD to use market', async () => { await systems().Core.connect(user1).mintUsd(accountId, 0, collateralAddress(), One); + await systems() + .Core.connect(user1) + .withdraw(accountId, await systems().Core.getUsdToken(), One); await systems().USD.connect(user1).approve(MockMarket().address, One); txn = await MockMarket().connect(user1).buySynth(One); }); diff --git a/protocol/synthetix/test/integration/modules/core/PoolModuleFundAdmin.test.ts b/protocol/synthetix/test/integration/modules/core/PoolModuleFundAdmin.test.ts index bec3006d58..221d20c60e 100644 --- a/protocol/synthetix/test/integration/modules/core/PoolModuleFundAdmin.test.ts +++ b/protocol/synthetix/test/integration/modules/core/PoolModuleFundAdmin.test.ts @@ -462,6 +462,9 @@ describe('PoolModule Admin', function () { // in the market, and then reset the market await systems().Core.connect(user1).mintUsd(accountId, 0, collateralAddress(), Hundred); + await systems() + .Core.connect(user1) + .withdraw(accountId, await systems().Core.getUsdToken(), Hundred); await systems().USD.connect(user1).approve(MockMarket().address, Hundred); await MockMarket().connect(user1).buySynth(Hundred); diff --git a/protocol/synthetix/test/integration/modules/core/USDTokenModule.test.ts b/protocol/synthetix/test/integration/modules/core/USDTokenModule.test.ts index b97383489a..5955e1ab57 100644 --- a/protocol/synthetix/test/integration/modules/core/USDTokenModule.test.ts +++ b/protocol/synthetix/test/integration/modules/core/USDTokenModule.test.ts @@ -61,6 +61,9 @@ describe('USDTokenModule', function () { let usdBalanceBefore: ethers.BigNumber; before('record balances', async () => { + await systems() + .Core.connect(staker()) + .withdraw(accountId, await systems().Core.getUsdToken(), fiftyUSD); usdBalanceBefore = await systems().USD.connect(staker()).balanceOf(stakerAddress); }); diff --git a/protocol/synthetix/test/integration/modules/core/VaultModule.test.ts b/protocol/synthetix/test/integration/modules/core/VaultModule.test.ts index 408f26b4ef..c72aa69914 100644 --- a/protocol/synthetix/test/integration/modules/core/VaultModule.test.ts +++ b/protocol/synthetix/test/integration/modules/core/VaultModule.test.ts @@ -489,6 +489,10 @@ describe('VaultModule', function () { collateralAddress(), depositAmount.div(100) // should be enough collateral to mint this ); + + await systems() + .Core.connect(user2) + .withdraw(user2AccountId, await systems().Core.getUsdToken(), depositAmount.div(100)); }); // lock enough collateral that the market will *become* capacity locked when the user From 214eb9bbb8390f0099b2b93527615a5919f4e176 Mon Sep 17 00:00:00 2001 From: Peiman Date: Wed, 9 Aug 2023 17:40:42 +0330 Subject: [PATCH 40/63] update storage --- markets/perps-market/storage.dump.sol | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/markets/perps-market/storage.dump.sol b/markets/perps-market/storage.dump.sol index 0a8e70c40b..3f16e37d2a 100644 --- a/markets/perps-market/storage.dump.sol +++ b/markets/perps-market/storage.dump.sol @@ -288,6 +288,7 @@ library Pool { uint64 __reserved1; uint64 __reserved2; uint64 __reserved3; + mapping(address => PoolCollateralConfiguration.Data) collateralConfigurations; } function load(uint128 id) internal pure returns (Data storage pool) { bytes32 s = keccak256(abi.encode("io.synthetix.synthetix.Pool", id)); @@ -297,6 +298,16 @@ library Pool { } } +// @custom:artifact @synthetixio/main/contracts/storage/PoolCollateralConfiguration.sol:PoolCollateralConfiguration +library PoolCollateralConfiguration { + bytes32 private constant _SLOT = keccak256(abi.encode("io.synthetix.synthetix.PoolCollateralConfiguration")); + struct Data { + uint256 maxDepositD18; + bool collateralTypeDisabled; + uint256 issuanceRatioD18; + } +} + // @custom:artifact @synthetixio/main/contracts/storage/RewardDistribution.sol:RewardDistribution library RewardDistribution { struct Data { From 9e937b633ede053eb2d3e669e764c2ec716c33ad Mon Sep 17 00:00:00 2001 From: Peiman Date: Wed, 9 Aug 2023 17:40:54 +0330 Subject: [PATCH 41/63] feat: update function name --- protocol/synthetix/contracts/modules/core/VaultModule.sol | 2 +- protocol/synthetix/contracts/storage/Pool.sol | 6 +++--- .../test/integration/modules/core/VaultModule.test.ts | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/protocol/synthetix/contracts/modules/core/VaultModule.sol b/protocol/synthetix/contracts/modules/core/VaultModule.sol index 3e5679486e..82e7a34f1d 100644 --- a/protocol/synthetix/contracts/modules/core/VaultModule.sol +++ b/protocol/synthetix/contracts/modules/core/VaultModule.sol @@ -88,7 +88,7 @@ contract VaultModule is IVaultModule { newCollateralAmountD18 - currentCollateralAmount ); - Pool.loadExisting(poolId).requireSufficientCollateralCapacity( + Pool.loadExisting(poolId).checkPoolCollateralLimit( collateralType, newCollateralAmountD18 - currentCollateralAmount ); diff --git a/protocol/synthetix/contracts/storage/Pool.sol b/protocol/synthetix/contracts/storage/Pool.sol index 13c70b3fd8..e4ca31fe27 100644 --- a/protocol/synthetix/contracts/storage/Pool.sol +++ b/protocol/synthetix/contracts/storage/Pool.sol @@ -53,7 +53,7 @@ library Pool { /** * @dev Thrown when pool has surpassed max collateral deposit */ - error SurpassedPoolMaxCollateralDeposit( + error PoolCollateralLimitExceeded( uint128 poolId, address collateralType, uint256 currentCollateral, @@ -526,7 +526,7 @@ library Pool { } } - function requireSufficientCollateralCapacity( + function checkPoolCollateralLimit( Data storage self, address collateralType, uint256 collateralAmountD18 @@ -537,7 +537,7 @@ library Pool { maxDeposit > 0 && self.vaults[collateralType].currentCollateral() + collateralAmountD18 > maxDeposit ) { - revert SurpassedPoolMaxCollateralDeposit( + revert PoolCollateralLimitExceeded( self.id, collateralType, self.vaults[collateralType].currentCollateral() + collateralAmountD18, diff --git a/protocol/synthetix/test/integration/modules/core/VaultModule.test.ts b/protocol/synthetix/test/integration/modules/core/VaultModule.test.ts index c72aa69914..1bd9b3159f 100644 --- a/protocol/synthetix/test/integration/modules/core/VaultModule.test.ts +++ b/protocol/synthetix/test/integration/modules/core/VaultModule.test.ts @@ -407,7 +407,7 @@ describe('VaultModule', function () { depositAmount.mul(2), ethers.utils.parseEther('1') ), - `SurpassedPoolMaxCollateralDeposit("${poolId}", "${collateralAddress()}", "${depositAmount + `PoolCollateralLimitExceeded("${poolId}", "${collateralAddress()}", "${depositAmount .mul(2) .toString()}", "${depositAmount.div(2).toString()}")`, systems().Core From 8c2b63a8dc3973944665e38e8fd5532da6a287cd Mon Sep 17 00:00:00 2001 From: Noisekit Date: Thu, 10 Aug 2023 07:11:05 +0800 Subject: [PATCH 42/63] Skip `docgen` checks in PRs and main (#1757) * Run docgen action only on special docgen branch and skip checking PRs and main NOTE: full auto mode with publishing to `synthetix-gitbook-v3` later * Update subgraph for perps * Skip subgraph checks for perps and spot markets --- .github/workflows/docgen.yml | 3 +- .../PerpsMarketProxy/PerpsMarketProxy.ts | 72 ++++++++++++++----- markets/perps-market/subgraph/package.json | 2 +- .../perps-market/subgraph/subgraph.base.yaml | 2 +- markets/spot-market/subgraph/package.json | 2 +- 5 files changed, 57 insertions(+), 24 deletions(-) diff --git a/.github/workflows/docgen.yml b/.github/workflows/docgen.yml index 4cea9c3074..57675078d8 100644 --- a/.github/workflows/docgen.yml +++ b/.github/workflows/docgen.yml @@ -1,10 +1,9 @@ name: Docgen on: - pull_request: {} push: branches: - - "main" + - "docgen" jobs: docgen: diff --git a/markets/perps-market/subgraph/generated/PerpsMarketProxy/PerpsMarketProxy.ts b/markets/perps-market/subgraph/generated/PerpsMarketProxy/PerpsMarketProxy.ts index 95774eb0db..9fa6c90d03 100644 --- a/markets/perps-market/subgraph/generated/PerpsMarketProxy/PerpsMarketProxy.ts +++ b/markets/perps-market/subgraph/generated/PerpsMarketProxy/PerpsMarketProxy.ts @@ -629,21 +629,25 @@ export class LiquidationParametersSet__Params { return this._event.parameters[2].value.toBigInt(); } - get liquidationRewardRatioD18(): BigInt { + get minimumInitialMarginRatioD18(): BigInt { return this._event.parameters[3].value.toBigInt(); } - get maxLiquidationLimitAccumulationMultiplier(): BigInt { + get liquidationRewardRatioD18(): BigInt { return this._event.parameters[4].value.toBigInt(); } - get maxSecondsInLiquidationWindow(): BigInt { + get maxLiquidationLimitAccumulationMultiplier(): BigInt { return this._event.parameters[5].value.toBigInt(); } - get minimumPositionMargin(): BigInt { + get maxSecondsInLiquidationWindow(): BigInt { return this._event.parameters[6].value.toBigInt(); } + + get minimumPositionMargin(): BigInt { + return this._event.parameters[7].value.toBigInt(); + } } export class LockedOiRatioSet extends ethereum.Event { @@ -1287,13 +1291,25 @@ export class PerpsMarketProxy__getLiquidationParametersResult { value2: BigInt; value3: BigInt; value4: BigInt; - - constructor(value0: BigInt, value1: BigInt, value2: BigInt, value3: BigInt, value4: BigInt) { + value5: BigInt; + value6: BigInt; + + constructor( + value0: BigInt, + value1: BigInt, + value2: BigInt, + value3: BigInt, + value4: BigInt, + value5: BigInt, + value6: BigInt + ) { this.value0 = value0; this.value1 = value1; this.value2 = value2; this.value3 = value3; this.value4 = value4; + this.value5 = value5; + this.value6 = value6; } toMap(): TypedMap { @@ -1303,6 +1319,8 @@ export class PerpsMarketProxy__getLiquidationParametersResult { map.set('value2', ethereum.Value.fromUnsignedBigInt(this.value2)); map.set('value3', ethereum.Value.fromUnsignedBigInt(this.value3)); map.set('value4', ethereum.Value.fromUnsignedBigInt(this.value4)); + map.set('value5', ethereum.Value.fromUnsignedBigInt(this.value5)); + map.set('value6', ethereum.Value.fromUnsignedBigInt(this.value6)); return map; } @@ -1310,21 +1328,29 @@ export class PerpsMarketProxy__getLiquidationParametersResult { return this.value0; } - getMaintenanceMarginRatioD18(): BigInt { + getMinimumInitialMarginRatioD18(): BigInt { return this.value1; } - getLiquidationRewardRatioD18(): BigInt { + getMaintenanceMarginScalarD18(): BigInt { return this.value2; } - getMaxLiquidationLimitAccumulationMultiplier(): BigInt { + getLiquidationRewardRatioD18(): BigInt { return this.value3; } - getMaxSecondsInLiquidationWindow(): BigInt { + getMaxLiquidationLimitAccumulationMultiplier(): BigInt { return this.value4; } + + getMaxSecondsInLiquidationWindow(): BigInt { + return this.value5; + } + + getMinimumPositionMargin(): BigInt { + return this.value6; + } } export class PerpsMarketProxy__getOrderFeesResult { @@ -2397,7 +2423,7 @@ export class PerpsMarketProxy extends ethereum.SmartContract { getLiquidationParameters(marketId: BigInt): PerpsMarketProxy__getLiquidationParametersResult { let result = super.call( 'getLiquidationParameters', - 'getLiquidationParameters(uint128):(uint256,uint256,uint256,uint256,uint256)', + 'getLiquidationParameters(uint128):(uint256,uint256,uint256,uint256,uint256,uint256,uint256)', [ethereum.Value.fromUnsignedBigInt(marketId)] ); @@ -2406,7 +2432,9 @@ export class PerpsMarketProxy extends ethereum.SmartContract { result[1].toBigInt(), result[2].toBigInt(), result[3].toBigInt(), - result[4].toBigInt() + result[4].toBigInt(), + result[5].toBigInt(), + result[6].toBigInt() ); } @@ -2415,7 +2443,7 @@ export class PerpsMarketProxy extends ethereum.SmartContract { ): ethereum.CallResult { let result = super.tryCall( 'getLiquidationParameters', - 'getLiquidationParameters(uint128):(uint256,uint256,uint256,uint256,uint256)', + 'getLiquidationParameters(uint128):(uint256,uint256,uint256,uint256,uint256,uint256,uint256)', [ethereum.Value.fromUnsignedBigInt(marketId)] ); if (result.reverted) { @@ -2428,7 +2456,9 @@ export class PerpsMarketProxy extends ethereum.SmartContract { value[1].toBigInt(), value[2].toBigInt(), value[3].toBigInt(), - value[4].toBigInt() + value[4].toBigInt(), + value[5].toBigInt(), + value[6].toBigInt() ) ); } @@ -3815,25 +3845,29 @@ export class SetLiquidationParametersCall__Inputs { return this._call.inputValues[1].value.toBigInt(); } - get maintenanceMarginRatioD18(): BigInt { + get minimumInitialMarginRatioD18(): BigInt { return this._call.inputValues[2].value.toBigInt(); } - get liquidationRewardRatioD18(): BigInt { + get maintenanceMarginScalarD18(): BigInt { return this._call.inputValues[3].value.toBigInt(); } - get maxLiquidationLimitAccumulationMultiplier(): BigInt { + get liquidationRewardRatioD18(): BigInt { return this._call.inputValues[4].value.toBigInt(); } - get maxSecondsInLiquidationWindow(): BigInt { + get maxLiquidationLimitAccumulationMultiplier(): BigInt { return this._call.inputValues[5].value.toBigInt(); } - get minimumPositionMargin(): BigInt { + get maxSecondsInLiquidationWindow(): BigInt { return this._call.inputValues[6].value.toBigInt(); } + + get minimumPositionMargin(): BigInt { + return this._call.inputValues[7].value.toBigInt(); + } } export class SetLiquidationParametersCall__Outputs { diff --git a/markets/perps-market/subgraph/package.json b/markets/perps-market/subgraph/package.json index 81fef99005..d342909da6 100644 --- a/markets/perps-market/subgraph/package.json +++ b/markets/perps-market/subgraph/package.json @@ -16,7 +16,7 @@ "build:optimism-goerli": "node ./codegen optimism-goerli && yarn codegen && graph build --output-dir ./build/optimism-goerli --network optimism-goerli", "deploy:optimism-goerli": "graph deploy --output-dir ./build/optimism-goerli --network optimism-goerli --product hosted-service snx-v3/v3-perps-opt-goerli", "test": "echo 'SKIP: No tests' || graph test", - "coverage": "yarn deployments:optimism-goerli && yarn codegen && git diff --exit-code && yarn test", + "coverage": "echo 'SKIP: No tests'", "create-local": "graph create --node http://localhost:8020/ snx-v3/goerli", "remove-local": "graph remove --node http://localhost:8020/ snx-v3/goerli", "deploy-local": "graph deploy --node http://localhost:8020/ --ipfs http://localhost:5001 snx-v3/goerli" diff --git a/markets/perps-market/subgraph/subgraph.base.yaml b/markets/perps-market/subgraph/subgraph.base.yaml index 9a0d49e07a..60644f56be 100644 --- a/markets/perps-market/subgraph/subgraph.base.yaml +++ b/markets/perps-market/subgraph/subgraph.base.yaml @@ -33,7 +33,7 @@ dataSources: handler: handleMarketPriceDataUpdated - event: FundingParametersSet(indexed uint128,uint256,uint256) handler: handleFundingParametersSet - - event: LiquidationParametersSet(indexed uint128,uint256,uint256,uint256,uint256,uint256,uint256) + - event: LiquidationParametersSet(indexed uint128,uint256,uint256,uint256,uint256,uint256,uint256,uint256) handler: handleLiquidationParametersSet - event: LockedOiRatioSet(indexed uint128,uint256) handler: handleLockedOiRatioSet diff --git a/markets/spot-market/subgraph/package.json b/markets/spot-market/subgraph/package.json index 070a9b5aa3..b4b4a9a0a4 100644 --- a/markets/spot-market/subgraph/package.json +++ b/markets/spot-market/subgraph/package.json @@ -16,7 +16,7 @@ "build:optimism-goerli": "node ./codegen optimism-goerli && yarn codegen && graph build --output-dir ./build/optimism-goerli --network optimism-goerli", "deploy:optimism-goerli": "graph deploy --output-dir ./build/optimism-goerli --network optimism-goerli --product hosted-service snx-v3/spot-market-optimism-goerli", "test": "echo 'SKIP: No tests' || graph test", - "coverage": "yarn deployments:optimism-goerli && yarn codegen && git diff --exit-code && yarn test", + "coverage": "echo 'SKIP: No tests'", "create-local": "graph create --node http://localhost:8020/ snx-v3/goerli", "remove-local": "graph remove --node http://localhost:8020/ snx-v3/goerli", "deploy-local": "graph deploy --node http://localhost:8020/ --ipfs http://localhost:5001 snx-v3/goerli" From fa1857c49553b42373c79be58e007d5efdb8ae9d Mon Sep 17 00:00:00 2001 From: Sunny Vempati <5723490+sunnyvempati@users.noreply.github.com> Date: Wed, 9 Aug 2023 18:36:54 -0500 Subject: [PATCH 43/63] Add view and modify event (#1754) * add more views * docgen * docgen round2 * add funding to subgraph --- docs/Contracts.md | 19 +++- .../IAsyncOrderSettlementModule.sol | 4 + .../interfaces/IGlobalPerpsMarketModule.sol | 6 ++ .../modules/AsyncOrderSettlementModule.sol | 3 +- .../modules/GlobalPerpsMarketModule.sol | 9 ++ markets/perps-market/docs/index.md | 19 +++- markets/perps-market/subgraph/schema.graphql | 1 + markets/perps-market/subgraph/src/orders.ts | 1 + .../perps-market/subgraph/subgraph.base.yaml | 2 +- .../integration/Market/CreateMarket.test.ts | 89 ------------------- .../Markets/GlobalPerpsMarket.test.ts | 14 ++- .../Orders/OffchainAsyncOrder.settle.test.ts | 1 + 12 files changed, 70 insertions(+), 98 deletions(-) diff --git a/docs/Contracts.md b/docs/Contracts.md index 72e8096b1d..e37b0fc77d 100644 --- a/docs/Contracts.md +++ b/docs/Contracts.md @@ -3891,7 +3891,7 @@ There is a synthetix v3 core system supply cap also set. If the current supply b #### OrderSettled ```solidity - event OrderSettled(uint128 marketId, uint128 accountId, uint256 fillPrice, int256 pnl, int128 sizeDelta, int128 newSize, uint256 totalFees, uint256 referralFees, uint256 collectedFees, uint256 settlementReward, bytes32 trackingCode, address settler) + event OrderSettled(uint128 marketId, uint128 accountId, uint256 fillPrice, int256 pnl, int256 accruedFunding, int128 sizeDelta, int128 newSize, uint256 totalFees, uint256 referralFees, uint256 collectedFees, uint256 settlementReward, bytes32 trackingCode, address settler) ``` Gets fired when a new order is settled. @@ -3900,7 +3900,8 @@ There is a synthetix v3 core system supply cap also set. If the current supply b * `marketId` (*uint128*) - Id of the market used for the trade. * `accountId` (*uint128*) - Id of the account used for the trade. * `fillPrice` (*uint256*) - Price at which the order was settled. -* `pnl` (*int256*) - +* `pnl` (*int256*) - Pnl of the previous closed position. +* `accruedFunding` (*int256*) - Accrued funding of the previous closed position. * `sizeDelta` (*int128*) - Size delta from order. * `newSize` (*int128*) - New size of the position after settlement. * `totalFees` (*uint256*) - Amount of fees collected by the protocol. @@ -4069,6 +4070,16 @@ There is a synthetix v3 core system supply cap also set. If the current supply b **Returns** * `shareRatioD18` (*uint256*) - The configured share percentage for the referrer +#### getMarkets + + ```solidity + function getMarkets() external returns (uint256[] marketIds) + ``` + + get all existing market ids + +**Returns** +* `marketIds` (*uint256[]*) - an array of existing market ids #### MaxCollateralAmountSet @@ -4578,7 +4589,7 @@ There is a synthetix v3 core system supply cap also set. If the current supply b #### getRequiredMargins ```solidity - function getRequiredMargins(uint128 accountId) external view returns (uint256 requiredInitialMargin, uint256 requiredMaintenanceMargin) + function getRequiredMargins(uint128 accountId) external view returns (uint256 requiredInitialMargin, uint256 requiredMaintenanceMargin, uint256 totalAccumulatedLiquidationRewards, uint256 maxLiquidationReward) ``` Gets the initial/maintenance margins across all positions that an account has open. @@ -4589,6 +4600,8 @@ There is a synthetix v3 core system supply cap also set. If the current supply b **Returns** * `requiredInitialMargin` (*uint256*) - initial margin req (used when withdrawing collateral). * `requiredMaintenanceMargin` (*uint256*) - maintenance margin req (used to determine liquidation threshold). +* `totalAccumulatedLiquidationRewards` (*uint256*) - sum of all liquidation rewards of if all account open positions were to be liquidated fully. +* `maxLiquidationReward` (*uint256*) - max liquidation reward the keeper would receive if account was fully liquidated. Note here that the accumulated rewards are checked against the global max/min configured liquidation rewards. #### CollateralModified diff --git a/markets/perps-market/contracts/interfaces/IAsyncOrderSettlementModule.sol b/markets/perps-market/contracts/interfaces/IAsyncOrderSettlementModule.sol index 52907feb08..e39d33a7af 100644 --- a/markets/perps-market/contracts/interfaces/IAsyncOrderSettlementModule.sol +++ b/markets/perps-market/contracts/interfaces/IAsyncOrderSettlementModule.sol @@ -25,6 +25,8 @@ interface IAsyncOrderSettlementModule { * @param marketId Id of the market used for the trade. * @param accountId Id of the account used for the trade. * @param fillPrice Price at which the order was settled. + * @param pnl Pnl of the previous closed position. + * @param accruedFunding Accrued funding of the previous closed position. * @param sizeDelta Size delta from order. * @param newSize New size of the position after settlement. * @param totalFees Amount of fees collected by the protocol. @@ -39,6 +41,7 @@ interface IAsyncOrderSettlementModule { uint128 indexed accountId, uint256 fillPrice, int256 pnl, + int256 accruedFunding, int128 sizeDelta, int128 newSize, uint256 totalFees, @@ -56,6 +59,7 @@ interface IAsyncOrderSettlementModule { int128 newPositionSize; int128 sizeDelta; int256 pnl; + int256 accruedFunding; uint256 pnlUint; uint256 amountToDeduct; uint256 settlementReward; diff --git a/markets/perps-market/contracts/interfaces/IGlobalPerpsMarketModule.sol b/markets/perps-market/contracts/interfaces/IGlobalPerpsMarketModule.sol index 924c500125..9181b49e47 100644 --- a/markets/perps-market/contracts/interfaces/IGlobalPerpsMarketModule.sol +++ b/markets/perps-market/contracts/interfaces/IGlobalPerpsMarketModule.sol @@ -131,4 +131,10 @@ interface IGlobalPerpsMarketModule { * @return shareRatioD18 The configured share percentage for the referrer */ function getReferrerShare(address referrer) external returns (uint256 shareRatioD18); + + /** + * @notice get all existing market ids + * @return marketIds an array of existing market ids + */ + function getMarkets() external returns (uint256[] memory marketIds); } diff --git a/markets/perps-market/contracts/modules/AsyncOrderSettlementModule.sol b/markets/perps-market/contracts/modules/AsyncOrderSettlementModule.sol index 57c157c7d5..1b55d8ef69 100644 --- a/markets/perps-market/contracts/modules/AsyncOrderSettlementModule.sol +++ b/markets/perps-market/contracts/modules/AsyncOrderSettlementModule.sol @@ -137,7 +137,7 @@ contract AsyncOrderSettlementModule is IAsyncOrderSettlementModule, IMarketEvent PerpsAccount.Data storage perpsAccount = PerpsAccount.load(runtime.accountId); // use fill price to calculate realized pnl - (runtime.pnl, , , , ) = oldPosition.getPnl(runtime.fillPrice); + (runtime.pnl, , , runtime.accruedFunding, ) = oldPosition.getPnl(runtime.fillPrice); runtime.pnlUint = MathUtil.abs(runtime.pnl); if (runtime.pnl > 0) { @@ -192,6 +192,7 @@ contract AsyncOrderSettlementModule is IAsyncOrderSettlementModule, IMarketEvent runtime.accountId, runtime.fillPrice, runtime.pnl, + runtime.accruedFunding, runtime.sizeDelta, runtime.newPositionSize, runtime.totalFees, diff --git a/markets/perps-market/contracts/modules/GlobalPerpsMarketModule.sol b/markets/perps-market/contracts/modules/GlobalPerpsMarketModule.sol index 28aca49539..aded0a9356 100644 --- a/markets/perps-market/contracts/modules/GlobalPerpsMarketModule.sol +++ b/markets/perps-market/contracts/modules/GlobalPerpsMarketModule.sol @@ -3,6 +3,7 @@ pragma solidity >=0.8.11 <0.9.0; import {DecimalMath} from "@synthetixio/core-contracts/contracts/utils/DecimalMath.sol"; import {ERC165Helper} from "@synthetixio/core-contracts/contracts/utils/ERC165Helper.sol"; +import {SetUtil} from "@synthetixio/core-contracts/contracts/utils/SetUtil.sol"; import {IFeeCollector} from "../interfaces/external/IFeeCollector.sol"; import {GlobalPerpsMarketConfiguration} from "../storage/GlobalPerpsMarketConfiguration.sol"; import {GlobalPerpsMarket} from "../storage/GlobalPerpsMarket.sol"; @@ -14,6 +15,7 @@ import {OwnableStorage} from "@synthetixio/core-contracts/contracts/ownership/Ow * @dev See IGlobalPerpsMarketModule. */ contract GlobalPerpsMarketModule is IGlobalPerpsMarketModule { + using SetUtil for SetUtil.UintSet; using GlobalPerpsMarketConfiguration for GlobalPerpsMarketConfiguration.Data; using GlobalPerpsMarket for GlobalPerpsMarket.Data; @@ -147,4 +149,11 @@ contract GlobalPerpsMarketModule is IGlobalPerpsMarketModule { ) external view override returns (uint256 shareRatioD18) { return GlobalPerpsMarketConfiguration.load().referrerShare[referrer]; } + + /** + * @inheritdoc IGlobalPerpsMarketModule + */ + function getMarkets() external view override returns (uint256[] memory marketIds) { + marketIds = GlobalPerpsMarket.load().activeMarkets.values(); + } } diff --git a/markets/perps-market/docs/index.md b/markets/perps-market/docs/index.md index 24396c2872..8f1fdd6cc0 100644 --- a/markets/perps-market/docs/index.md +++ b/markets/perps-market/docs/index.md @@ -91,7 +91,7 @@ #### OrderSettled ```solidity - event OrderSettled(uint128 marketId, uint128 accountId, uint256 fillPrice, int256 pnl, int128 sizeDelta, int128 newSize, uint256 totalFees, uint256 referralFees, uint256 collectedFees, uint256 settlementReward, bytes32 trackingCode, address settler) + event OrderSettled(uint128 marketId, uint128 accountId, uint256 fillPrice, int256 pnl, int256 accruedFunding, int128 sizeDelta, int128 newSize, uint256 totalFees, uint256 referralFees, uint256 collectedFees, uint256 settlementReward, bytes32 trackingCode, address settler) ``` Gets fired when a new order is settled. @@ -100,7 +100,8 @@ * `marketId` (*uint128*) - Id of the market used for the trade. * `accountId` (*uint128*) - Id of the account used for the trade. * `fillPrice` (*uint256*) - Price at which the order was settled. -* `pnl` (*int256*) - +* `pnl` (*int256*) - Pnl of the previous closed position. +* `accruedFunding` (*int256*) - Accrued funding of the previous closed position. * `sizeDelta` (*int128*) - Size delta from order. * `newSize` (*int128*) - New size of the position after settlement. * `totalFees` (*uint256*) - Amount of fees collected by the protocol. @@ -269,6 +270,16 @@ **Returns** * `shareRatioD18` (*uint256*) - The configured share percentage for the referrer +#### getMarkets + + ```solidity + function getMarkets() external returns (uint256[] marketIds) + ``` + + get all existing market ids + +**Returns** +* `marketIds` (*uint256[]*) - an array of existing market ids #### MaxCollateralAmountSet @@ -778,7 +789,7 @@ #### getRequiredMargins ```solidity - function getRequiredMargins(uint128 accountId) external view returns (uint256 requiredInitialMargin, uint256 requiredMaintenanceMargin) + function getRequiredMargins(uint128 accountId) external view returns (uint256 requiredInitialMargin, uint256 requiredMaintenanceMargin, uint256 totalAccumulatedLiquidationRewards, uint256 maxLiquidationReward) ``` Gets the initial/maintenance margins across all positions that an account has open. @@ -789,6 +800,8 @@ **Returns** * `requiredInitialMargin` (*uint256*) - initial margin req (used when withdrawing collateral). * `requiredMaintenanceMargin` (*uint256*) - maintenance margin req (used to determine liquidation threshold). +* `totalAccumulatedLiquidationRewards` (*uint256*) - sum of all liquidation rewards of if all account open positions were to be liquidated fully. +* `maxLiquidationReward` (*uint256*) - max liquidation reward the keeper would receive if account was fully liquidated. Note here that the accumulated rewards are checked against the global max/min configured liquidation rewards. #### CollateralModified diff --git a/markets/perps-market/subgraph/schema.graphql b/markets/perps-market/subgraph/schema.graphql index 8c8c6511c6..5b371f0e11 100644 --- a/markets/perps-market/subgraph/schema.graphql +++ b/markets/perps-market/subgraph/schema.graphql @@ -121,6 +121,7 @@ type OrderSettled @entity { marketId: BigInt! accountId: BigInt! fillPrice: BigInt! + accruedFunding: BigInt! sizeDelta: BigInt! newSize: BigInt! totalFees: BigInt! diff --git a/markets/perps-market/subgraph/src/orders.ts b/markets/perps-market/subgraph/src/orders.ts index ee32a54921..eabd985191 100644 --- a/markets/perps-market/subgraph/src/orders.ts +++ b/markets/perps-market/subgraph/src/orders.ts @@ -93,6 +93,7 @@ export function handleOrderSettled(event: OrderSettledEvent): void { orderSettled.marketId = event.params.marketId; orderSettled.accountId = event.params.accountId; orderSettled.fillPrice = event.params.fillPrice; + orderSettled.accruedFunding = event.params.accruedFunding; orderSettled.sizeDelta = event.params.sizeDelta; orderSettled.newSize = event.params.newSize; orderSettled.totalFees = event.params.totalFees; diff --git a/markets/perps-market/subgraph/subgraph.base.yaml b/markets/perps-market/subgraph/subgraph.base.yaml index 60644f56be..659a226923 100644 --- a/markets/perps-market/subgraph/subgraph.base.yaml +++ b/markets/perps-market/subgraph/subgraph.base.yaml @@ -45,7 +45,7 @@ dataSources: handler: handleSettlementStrategyEnabled - event: OrderCommitted(indexed uint128,indexed uint128,uint8,int128,uint256,uint256,uint256,indexed bytes32,address) handler: handleOrderCommitted - - event: OrderSettled(indexed uint128,indexed uint128,uint256,int256,int128,int128,uint256,uint256,uint256,uint256,indexed bytes32,address) + - event: OrderSettled(indexed uint128,indexed uint128,uint256,int256,int256,int128,int128,uint256,uint256,uint256,uint256,indexed bytes32,address) handler: handleOrderSettled - event: PositionLiquidated(indexed uint128,indexed uint128,uint256,int128) handler: handlePositionLiquidated diff --git a/markets/perps-market/test/integration/Market/CreateMarket.test.ts b/markets/perps-market/test/integration/Market/CreateMarket.test.ts index 875be5e879..7576bc30c2 100644 --- a/markets/perps-market/test/integration/Market/CreateMarket.test.ts +++ b/markets/perps-market/test/integration/Market/CreateMarket.test.ts @@ -64,95 +64,6 @@ describe('Create Market test', () => { }); }); - // TODO: move to proxy level test - // describe('change ownership', async () => { - // before(restore); - - // let tx: ethers.providers.TransactionResponse; - - // before('create perps market', async () => { - // marketId = await systems().PerpsMarket.callStatic.createMarket( - // name, - // token, - // marketOwner.getAddress() - // ); - // await systems().PerpsMarket.createMarket(name, token, marketOwner.getAddress()); - // }); - - // describe('some account other than owner', () => { - // it('reverts attempt to change ownership', async () => { - // await assertRevert( - // systems() - // .PerpsMarket.connect(randomAccount) - // .nominateMarketOwner(marketId, anotherOwner.getAddress()), - // 'Unauthorized' - // ); - // }); - - // it('reverts attempt to accept ownership', async () => { - // await assertRevert( - // systems().PerpsMarket.connect(randomAccount).acceptMarketOwnership(marketId), - // 'NotNominated' - // ); - // }); - // }); - - // describe('owner nominates address zero', () => { - // it('reverts', async () => { - // await assertRevert( - // systems() - // .PerpsMarket.connect(marketOwner) - // .nominateMarketOwner(marketId, ethers.constants.AddressZero), - // 'ZeroAddress' - // ); - // }); - // }); - - // describe('owner nominates', () => { - // before('nominate', async () => { - // tx = await systems() - // .PerpsMarket.connect(marketOwner) - // .nominateMarketOwner(marketId, anotherOwner.getAddress()); - // }); - - // it('emits event', async () => { - // await assertEvent( - // tx, - // `MarketOwnerNominated(${marketId}, "${await anotherOwner.getAddress()}")`, - // systems().PerpsMarket - // ); - // }); - - // it('reverts if accepted by other address', async () => { - // await assertRevert( - // systems().PerpsMarket.connect(randomAccount).acceptMarketOwnership(marketId), - // 'NotNominated' - // ); - // }); - - // describe('nominated address accepts', () => { - // before('accept', async () => { - // tx = await systems().PerpsMarket.connect(anotherOwner).acceptMarketOwnership(marketId); - // }); - - // it('emits event', async () => { - // await assertEvent( - // tx, - // `MarketOwnerChanged(${marketId}, "${await marketOwner.getAddress()}", "${await anotherOwner.getAddress()}")`, - // systems().PerpsMarket - // ); - // }); - - // it('changed owner', async () => { - // assert.equal( - // await systems().PerpsMarket.getMarketOwner(marketId), - // await anotherOwner.getAddress() - // ); - // }); - // }); - // }); - // }); - describe('market operation and configuration', async () => { before(restore); diff --git a/markets/perps-market/test/integration/Markets/GlobalPerpsMarket.test.ts b/markets/perps-market/test/integration/Markets/GlobalPerpsMarket.test.ts index 90a112e7dc..78f1006b19 100644 --- a/markets/perps-market/test/integration/Markets/GlobalPerpsMarket.test.ts +++ b/markets/perps-market/test/integration/Markets/GlobalPerpsMarket.test.ts @@ -6,7 +6,10 @@ import assertRevert from '@synthetixio/core-utils/utils/assertions/assert-revert describe('GlobalPerpsMarket', () => { const { systems, perpsMarkets, trader1 } = bootstrapMarkets({ synthMarkets: [{ name: 'Ether', token: 'snxETH', buyPrice: bn(1000), sellPrice: bn(1000) }], - perpsMarkets: [{ requestedMarketId: 25, name: 'Ether', token: 'snxETH', price: bn(1000) }], + perpsMarkets: [ + { requestedMarketId: 25, name: 'Ether', token: 'snxETH', price: bn(1000) }, + { requestedMarketId: 50, name: 'Btc', token: 'snxBTC', price: bn(10000) }, + ], traderAccountIds: [], }); @@ -55,4 +58,13 @@ describe('GlobalPerpsMarket', () => { `Unauthorized("${await trader1().getAddress()}")` ); }); + + describe('getMarkets()', () => { + it('returns all markets', async () => { + const markets = await systems().PerpsMarket.getMarkets(); + assertBn.equal(markets.length, 2); + assertBn.equal(markets[0], perpsMarkets()[0].marketId()); + assertBn.equal(markets[1], perpsMarkets()[1].marketId()); + }); + }); }); diff --git a/markets/perps-market/test/integration/Orders/OffchainAsyncOrder.settle.test.ts b/markets/perps-market/test/integration/Orders/OffchainAsyncOrder.settle.test.ts index 1f7a863317..dfa0a2518b 100644 --- a/markets/perps-market/test/integration/Orders/OffchainAsyncOrder.settle.test.ts +++ b/markets/perps-market/test/integration/Orders/OffchainAsyncOrder.settle.test.ts @@ -375,6 +375,7 @@ describe('Settle Offchain Async Order test', () => { accountId, fillPrice, 0, + 0, sizeDelta, newPositionSize, totalFees, From c40b8a4277af2e6ca8aa1ea0fe8162bf6a03cd5f Mon Sep 17 00:00:00 2001 From: Noisekit Date: Fri, 11 Aug 2023 13:11:08 +0800 Subject: [PATCH 44/63] Make sure we fail build when tests fail, but do not fail-fast and run all tests without cancelling them (#1761) --- .github/workflows/check-packages.yml | 6 +++++- .github/workflows/lint.yml | 8 +++++++- .github/workflows/simulate-release.yml | 1 + .github/workflows/test.yml | 2 +- 4 files changed, 14 insertions(+), 3 deletions(-) diff --git a/.github/workflows/check-packages.yml b/.github/workflows/check-packages.yml index 4617d40b74..8d6a6ae61c 100644 --- a/.github/workflows/check-packages.yml +++ b/.github/workflows/check-packages.yml @@ -1,6 +1,10 @@ name: "Validate yarn.lock and cache" -on: [pull_request] +on: + pull_request: {} + push: + branches: + - "main" jobs: check: diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 3532636175..8a12915736 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -1,5 +1,11 @@ name: Lint -on: [push] + +on: + pull_request: {} + push: + branches: + - "main" + jobs: lint: runs-on: ubuntu-latest diff --git a/.github/workflows/simulate-release.yml b/.github/workflows/simulate-release.yml index 875d1366cd..f08cd1b0cb 100644 --- a/.github/workflows/simulate-release.yml +++ b/.github/workflows/simulate-release.yml @@ -15,6 +15,7 @@ jobs: CANNON_IPFS_URL: "http://127.0.0.1:5001" CANNON_PUBLISH_IPFS_URL: "http://127.0.0.1:5001" strategy: + fail-fast: false matrix: network: [goerli, optimistic-goerli] project: [protocol/oracle-manager, protocol/synthetix] diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 01b734ac9a..4d797c152c 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -9,11 +9,11 @@ on: jobs: test: runs-on: ubuntu-latest - continue-on-error: true env: CANNON_IPFS_URL: "http://127.0.0.1:5001" CANNON_PUBLISH_IPFS_URL: "http://127.0.0.1:5001" strategy: + fail-fast: false matrix: package: [ From 5b06e5d1e2483a923a57d99494d44f1e9567449e Mon Sep 17 00:00:00 2001 From: Noisekit Date: Fri, 11 Aug 2023 13:43:38 +0800 Subject: [PATCH 45/63] Run only tests for PRs and run tests and coverage report (where possible) on main branch only (#1762) --- .github/workflows/test-with-coverage.yml | 114 +++++++++++++++++++++++ .github/workflows/test.yml | 80 +++++----------- 2 files changed, 138 insertions(+), 56 deletions(-) create mode 100644 .github/workflows/test-with-coverage.yml diff --git a/.github/workflows/test-with-coverage.yml b/.github/workflows/test-with-coverage.yml new file mode 100644 index 0000000000..a3ec868cb4 --- /dev/null +++ b/.github/workflows/test-with-coverage.yml @@ -0,0 +1,114 @@ +name: Coverage + +on: + push: + branches: + - "main" + +jobs: + coverage: + runs-on: ubuntu-latest + env: + CANNON_IPFS_URL: "http://127.0.0.1:5001" + CANNON_PUBLISH_IPFS_URL: "http://127.0.0.1:5001" + strategy: + fail-fast: false + matrix: + workspace: [ + "@synthetixio/main", + "@synthetixio/oracle-manager", + # "@synthetixio/governance", # no tests :/ + + "@synthetixio/core-contracts", + "@synthetixio/core-utils", + "@synthetixio/core-modules", + "@synthetixio/hardhat-storage", + "@synthetixio/sample-project", + + # "@synthetixio/legacy-market", # tests fail + "@synthetixio/spot-market", + "@synthetixio/perps-market", + + "@synthetixio/core-subgraph", + "@synthetixio/spot-market-subgraph", + "@synthetixio/perps-market-subgraph", + ] + + include: + - workspace: "@synthetixio/main" + codecov-file: protocol/synthetix/coverage.json + codecov-flags: main + + - workspace: "@synthetixio/oracle-manager" + codecov-file: protocol/oracle-manager/coverage.json + codecov-flags: oracle-manager + + - workspace: "@synthetixio/core-contracts" + codecov-file: utils/core-contracts/coverage.json + codecov-flags: core-contracts + + - workspace: "@synthetixio/core-utils" + codecov-file: utils/core-utils/coverage/lcov.info + codecov-flags: core-utils + + - workspace: "@synthetixio/core-modules" + codecov-file: utils/core-modules/coverage.json + codecov-flags: core-modules + + - workspace: "@synthetixio/hardhat-storage" + codecov-file: utils/hardhat-storage/coverage/lcov.info + codecov-flags: hardhat-storage + + - workspace: "@synthetixio/sample-project" + codecov-file: utils/sample-project/coverage.json + codecov-flags: sample-project + + steps: + - name: Install Foundry (Cannon) + uses: foundry-rs/foundry-toolchain@v1 + with: + version: nightly + - run: anvil -V + - uses: actions/checkout@v3 + - uses: actions/setup-node@v3 + with: + node-version: "16.20.1" + cache: "yarn" + - uses: ibnesayeed/setup-ipfs@92d412e0dad36c06ffab50733e9c624896a0964f + with: + run_daemon: true + + - run: yarn install --immutable --immutable-cache + - run: yarn workspaces foreach --topological-dev --recursive --verbose --from "${{ matrix.workspace }}" run build:ts + - run: yarn workspaces foreach --topological-dev --recursive --verbose --from "${{ matrix.workspace }}" run build-testable + + - name: Execute size-contracts command + run: | + if yarn workspace ${{ matrix.workspace }} run | grep size-contracts; then + yarn workspace ${{ matrix.workspace }} run size-contracts + else + echo 'SKIP. No "size-contracts" script' + fi + + - name: Check storage.dump.sol is up-to-date + run: | + if yarn workspace ${{ matrix.workspace }} run | grep check:storage; then + yarn workspace ${{ matrix.workspace }} run check:storage + else + echo 'SKIP. No "check:storage" script' + fi + + - name: Execute tests with coverage + run: | + if yarn workspace ${{ matrix.workspace }} run | grep coverage; then + REPORT_GAS=true yarn workspace ${{ matrix.workspace }} run coverage + else + echo 'SKIP. No "coverage" script' + fi + + - if: ${{ matrix.codecov-file }} + name: Upload ${{ matrix.workspace }} coverage to Codecov + uses: codecov/codecov-action@v2 + with: + files: ${{ matrix.codecov-file }} + flags: ${{ matrix.codecov-flags }} diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 4d797c152c..ccb1b13388 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -2,9 +2,6 @@ name: Test on: pull_request: {} - push: - branches: - - "main" jobs: test: @@ -15,46 +12,26 @@ jobs: strategy: fail-fast: false matrix: - package: - [ - core-contracts, - core-utils, - core-modules, - sample-project, - main, - oracle-manager, - spot-market, - perps-market, - core-subgraph, - spot-market-subgraph, - perps-market-subgraph, + workspace: [ + "@synthetixio/main", + "@synthetixio/oracle-manager", + # "@synthetixio/governance", # no tests :/ + + "@synthetixio/core-contracts", + "@synthetixio/core-utils", + "@synthetixio/core-modules", + "@synthetixio/hardhat-storage", + "@synthetixio/sample-project", + + # "@synthetixio/legacy-market", # tests fail + "@synthetixio/spot-market", + "@synthetixio/perps-market", + + "@synthetixio/core-subgraph", + "@synthetixio/spot-market-subgraph", + "@synthetixio/perps-market-subgraph", ] - include: - - package: core-contracts - workspace: "@synthetixio/core-contracts" - coverage-file: utils/core-contracts/coverage.json - - package: core-utils - workspace: "@synthetixio/core-utils" - coverage-file: utils/core-utils/coverage/lcov.info - - package: core-modules - workspace: "@synthetixio/core-modules" - coverage-file: utils/core-modules/coverage.json - - package: sample-project - workspace: "@synthetixio/sample-project" - - package: oracle-manager - workspace: "@synthetixio/oracle-manager" - - package: spot-market - workspace: "@synthetixio/spot-market" - - package: perps-market - workspace: "@synthetixio/perps-market" - - package: main - workspace: "@synthetixio/main" - - package: core-subgraph - workspace: "@synthetixio/core-subgraph" - - package: spot-market-subgraph - workspace: "@synthetixio/spot-market-subgraph" - - package: perps-market-subgraph - workspace: "@synthetixio/perps-market-subgraph" + steps: - name: Install Foundry (Cannon) uses: foundry-rs/foundry-toolchain@v1 @@ -71,10 +48,8 @@ jobs: run_daemon: true - run: yarn install --immutable --immutable-cache - - - run: yarn workspaces foreach --topological-dev --recursive --verbose --from ${{ matrix.workspace }} run build:ts - - - run: yarn workspaces foreach --topological-dev --recursive --verbose --from ${{ matrix.workspace }} run build-testable + - run: yarn workspaces foreach --topological-dev --recursive --verbose --from "${{ matrix.workspace }}" run build:ts + - run: yarn workspaces foreach --topological-dev --recursive --verbose --from "${{ matrix.workspace }}" run build-testable - name: Execute size-contracts command run: | @@ -94,15 +69,8 @@ jobs: - name: Execute tests run: | - if yarn workspace ${{ matrix.workspace }} run | grep coverage; then - REPORT_GAS=true yarn workspace ${{ matrix.workspace }} run coverage + if yarn workspace ${{ matrix.workspace }} run | grep test; then + REPORT_GAS=true yarn workspace ${{ matrix.workspace }} run test else - echo 'SKIP. No "coverage" script' + echo 'SKIP. No "test" script' fi - - - if: ${{ matrix.coverage-file }} - name: Upload ${{ matrix.workspace }} coverage to Codecov - uses: codecov/codecov-action@v2 - with: - files: ${{ matrix.coverage-file }} - flags: ${{ matrix.package }} From d4117766528918cc3615bc39d65aaa1f4d26134d Mon Sep 17 00:00:00 2001 From: Sunny Vempati <5723490+sunnyvempati@users.noreply.github.com> Date: Fri, 11 Aug 2023 10:25:15 -0500 Subject: [PATCH 46/63] getMarginForOrder function (#1759) * add new order margin func * fix order fees --- .../interfaces/IAsyncOrderModule.sol | 17 ++++++- .../contracts/modules/AsyncOrderModule.sol | 47 +++++++++++++++++-- .../contracts/storage/AsyncOrder.sol | 6 +-- .../contracts/storage/PerpsMarket.sol | 7 +++ .../Orders/OffchainAsyncOrder.fees.test.ts | 6 +-- .../OffchainAsyncOrder.referrer.test.ts | 34 +++++++++----- .../Orders/Order.marginValidation.test.ts | 30 +++++++++--- .../maxSize.ts} | 0 8 files changed, 116 insertions(+), 31 deletions(-) rename markets/perps-market/test/integration/{Orders/GetOrderFees.test.ts => helpers/maxSize.ts} (100%) diff --git a/markets/perps-market/contracts/interfaces/IAsyncOrderModule.sol b/markets/perps-market/contracts/interfaces/IAsyncOrderModule.sol index 3e572bb14b..b4fbc494ad 100644 --- a/markets/perps-market/contracts/interfaces/IAsyncOrderModule.sol +++ b/markets/perps-market/contracts/interfaces/IAsyncOrderModule.sol @@ -55,9 +55,24 @@ interface IAsyncOrderModule { * @param marketId id of the market. * @param sizeDelta size of position. * @return orderFees incurred fees. + * @return fillPrice price at which the order would be filled. */ function computeOrderFees( uint128 marketId, int128 sizeDelta - ) external view returns (uint256 orderFees); + ) external view returns (uint256 orderFees, uint256 fillPrice); + + /** + * @notice For a given market, account id, and a position size, returns the required total account margin for this order to succeed + * @dev Useful for integrators to determine if an order will succeed or fail + * @param marketId id of the market. + * @param accountId id of the trader account. + * @param sizeDelta size of position. + * @return requiredMargin margin required for the order to succeed. + */ + function requiredMarginForOrder( + uint128 marketId, + uint128 accountId, + int128 sizeDelta + ) external view returns (uint256 requiredMargin); } diff --git a/markets/perps-market/contracts/modules/AsyncOrderModule.sol b/markets/perps-market/contracts/modules/AsyncOrderModule.sol index 84af91bf50..18b2296d4c 100644 --- a/markets/perps-market/contracts/modules/AsyncOrderModule.sol +++ b/markets/perps-market/contracts/modules/AsyncOrderModule.sol @@ -7,7 +7,9 @@ import {Account} from "@synthetixio/main/contracts/storage/Account.sol"; import {AccountRBAC} from "@synthetixio/main/contracts/storage/AccountRBAC.sol"; import {IAsyncOrderModule} from "../interfaces/IAsyncOrderModule.sol"; import {PerpsMarket} from "../storage/PerpsMarket.sol"; +import {PerpsAccount} from "../storage/PerpsAccount.sol"; import {AsyncOrder} from "../storage/AsyncOrder.sol"; +import {Position} from "../storage/Position.sol"; import {PerpsPrice} from "../storage/PerpsPrice.sol"; import {GlobalPerpsMarket} from "../storage/GlobalPerpsMarket.sol"; import {PerpsMarketConfiguration} from "../storage/PerpsMarketConfiguration.sol"; @@ -24,6 +26,7 @@ contract AsyncOrderModule is IAsyncOrderModule { using PerpsPrice for PerpsPrice.Data; using PerpsMarket for PerpsMarket.Data; using AsyncOrder for AsyncOrder.Data; + using PerpsAccount for PerpsAccount.Data; using SettlementStrategy for SettlementStrategy.Data; using GlobalPerpsMarket for GlobalPerpsMarket.Data; using PerpsMarketConfiguration for PerpsMarketConfiguration.Data; @@ -89,13 +92,49 @@ contract AsyncOrderModule is IAsyncOrderModule { function computeOrderFees( uint128 marketId, int128 sizeDelta - ) external view override returns (uint256 orderFees) { - PerpsMarket.Data storage perpsMarket = PerpsMarket.load(marketId); - int256 skew = perpsMarket.skew; + ) external view override returns (uint256 orderFees, uint256 fillPrice) { + (orderFees, fillPrice) = _computeOrderFees(marketId, sizeDelta); + } + + function requiredMarginForOrder( + uint128 accountId, + uint128 marketId, + int128 sizeDelta + ) external view override returns (uint256 requiredMargin) { + PerpsMarketConfiguration.Data storage marketConfig = PerpsMarketConfiguration.load( + marketId + ); + + Position.Data storage oldPosition = PerpsMarket.accountPosition(marketId, accountId); + ( + , + uint256 currentMaintenanceMargin, + uint256 currentTotalLiquidationRewards, + + ) = PerpsAccount.load(accountId).getAccountRequiredMargins(); + (uint256 orderFees, uint256 fillPrice) = _computeOrderFees(marketId, sizeDelta); + + return + AsyncOrder.getRequiredMarginWithNewPosition( + marketConfig, + marketId, + oldPosition.size, + oldPosition.size + sizeDelta, + fillPrice, + currentMaintenanceMargin, + currentTotalLiquidationRewards + ) + orderFees; + } + + function _computeOrderFees( + uint128 marketId, + int128 sizeDelta + ) private view returns (uint256 orderFees, uint256 fillPrice) { + int256 skew = PerpsMarket.load(marketId).skew; PerpsMarketConfiguration.Data storage marketConfig = PerpsMarketConfiguration.load( marketId ); - uint256 fillPrice = AsyncOrder.calculateFillPrice( + fillPrice = AsyncOrder.calculateFillPrice( skew, marketConfig.skewScale, sizeDelta, diff --git a/markets/perps-market/contracts/storage/AsyncOrder.sol b/markets/perps-market/contracts/storage/AsyncOrder.sol index 80fb2aaf53..463703fba4 100644 --- a/markets/perps-market/contracts/storage/AsyncOrder.sol +++ b/markets/perps-market/contracts/storage/AsyncOrder.sol @@ -328,7 +328,7 @@ library AsyncOrder { revert InsufficientMargin(runtime.currentAvailableMargin, runtime.orderFees); } - oldPosition = PerpsMarket.load(runtime.marketId).positions[runtime.accountId]; + oldPosition = PerpsMarket.accountPosition(runtime.marketId, runtime.accountId); PerpsMarket.validatePositionSize( perpsMarketData, @@ -339,7 +339,7 @@ library AsyncOrder { runtime.newPositionSize = oldPosition.size + runtime.sizeDelta; runtime.totalRequiredMargin = - _getRequiredMarginWithNewPosition( + getRequiredMarginWithNewPosition( marketConfig, runtime.marketId, oldPosition.size, @@ -466,7 +466,7 @@ library AsyncOrder { * @notice After the required margins are calculated with the old position, this function replaces the * old position data with the new position margin requirements and returns them. */ - function _getRequiredMarginWithNewPosition( + function getRequiredMarginWithNewPosition( PerpsMarketConfiguration.Data storage marketConfig, uint128 marketId, int128 oldPositionSize, diff --git a/markets/perps-market/contracts/storage/PerpsMarket.sol b/markets/perps-market/contracts/storage/PerpsMarket.sol index dc5934c15e..31e2a6ac23 100644 --- a/markets/perps-market/contracts/storage/PerpsMarket.sol +++ b/markets/perps-market/contracts/storage/PerpsMarket.sol @@ -310,4 +310,11 @@ library PerpsMarket { return traderUnrealizedPnl + unrealizedFunding - self.debtCorrectionAccumulator; } + + function accountPosition( + uint128 marketId, + uint128 accountId + ) internal view returns (Position.Data storage position) { + position = load(marketId).positions[accountId]; + } } diff --git a/markets/perps-market/test/integration/Orders/OffchainAsyncOrder.fees.test.ts b/markets/perps-market/test/integration/Orders/OffchainAsyncOrder.fees.test.ts index a5ef78bece..241b621da0 100644 --- a/markets/perps-market/test/integration/Orders/OffchainAsyncOrder.fees.test.ts +++ b/markets/perps-market/test/integration/Orders/OffchainAsyncOrder.fees.test.ts @@ -155,10 +155,8 @@ describe('Offchain Async Order test - fees', () => { }); it('returns proper fees on getOrderFees', async () => { - assertBn.equal( - await systems().PerpsMarket.computeOrderFees(ethMarketId, sizeDelta), - feesPaidOnSettle.perpsMarketFee - ); + const [orderFees] = await systems().PerpsMarket.computeOrderFees(ethMarketId, sizeDelta); + assertBn.equal(orderFees, feesPaidOnSettle.perpsMarketFee); }); it('validate that not fees are paid on commit', async () => { diff --git a/markets/perps-market/test/integration/Orders/OffchainAsyncOrder.referrer.test.ts b/markets/perps-market/test/integration/Orders/OffchainAsyncOrder.referrer.test.ts index 7ea6ffb480..a452232c2f 100644 --- a/markets/perps-market/test/integration/Orders/OffchainAsyncOrder.referrer.test.ts +++ b/markets/perps-market/test/integration/Orders/OffchainAsyncOrder.referrer.test.ts @@ -73,9 +73,11 @@ describe('OffchainAsyncOrder - feeCollector - referrer', () => { before('identify data', async () => { beforeWithdrawableUsd = wei(await systems().Core.getWithdrawableMarketUsd(superMarketId())); // NOTE: expected fees here does not include settlement reward - expectedFees = wei( - await systems().PerpsMarket.computeOrderFees(perpsMarkets()[0].marketId(), sizeDelta) + const [fees] = await systems().PerpsMarket.computeOrderFees( + perpsMarkets()[0].marketId(), + sizeDelta ); + expectedFees = wei(fees); expectedToReferrer = expectedFees.mul(referrerRatio); expectedToFeeCollector = expectedFees.sub(expectedToReferrer).mul(feeCollectorRatio); }); @@ -135,9 +137,11 @@ describe('OffchainAsyncOrder - feeCollector - referrer', () => { before('identify data', async () => { previousReferrerBalance = wei(await systems().USD.balanceOf(await referrer.getAddress())); // NOTE: expected fees here does not include settlement reward - const expectedFees = wei( - await systems().PerpsMarket.computeOrderFees(perpsMarkets()[0].marketId(), sizeDelta) + const [fees] = await systems().PerpsMarket.computeOrderFees( + perpsMarkets()[0].marketId(), + sizeDelta ); + const expectedFees = wei(fees); const currentFeeCollectorBalance = wei( await systems().USD.balanceOf(systems().FeeCollectorMock.address) ); @@ -185,10 +189,12 @@ describe('OffchainAsyncOrder - feeCollector - referrer', () => { previousFeeCollectorBalance = wei( await systems().USD.balanceOf(systems().FeeCollectorMock.address) ); - // NOTE: expected fees here does not include settlement reward - const expectedFees = wei( - await systems().PerpsMarket.computeOrderFees(perpsMarkets()[0].marketId(), sizeDelta) + const [orderFees] = await systems().PerpsMarket.computeOrderFees( + perpsMarkets()[0].marketId(), + sizeDelta ); + // NOTE: expected fees here does not include settlement reward + const expectedFees = wei(orderFees); const currentReferrerBalance = wei( await systems().USD.balanceOf(await referrer.getAddress()) ); @@ -233,10 +239,12 @@ describe('OffchainAsyncOrder - feeCollector - referrer', () => { let expectedToReferrer: Wei, expectedToFeeCollector: Wei; const sizeDelta = bn(25); before('identify data', async () => { - // NOTE: expected fees here does not include settlement reward - const expectedFees = wei( - await systems().PerpsMarket.computeOrderFees(perpsMarkets()[0].marketId(), sizeDelta) + const [orderFees] = await systems().PerpsMarket.computeOrderFees( + perpsMarkets()[0].marketId(), + sizeDelta ); + // NOTE: expected fees here does not include settlement reward + const expectedFees = wei(orderFees); const currentFeeCollectorBalance = wei( await systems().USD.balanceOf(systems().FeeCollectorMock.address) ); @@ -292,9 +300,11 @@ describe('OffchainAsyncOrder - feeCollector - referrer', () => { await systems().USD.balanceOf(systems().FeeCollectorMock.address) ); // NOTE: expected fees here does not include settlement reward - const expectedFees = wei( - await systems().PerpsMarket.computeOrderFees(perpsMarkets()[0].marketId(), sizeDelta) + const [fees] = await systems().PerpsMarket.computeOrderFees( + perpsMarkets()[0].marketId(), + sizeDelta ); + const expectedFees = wei(fees); const currentReferrerBalance = wei( await systems().USD.balanceOf(await referrer.getAddress()) ); diff --git a/markets/perps-market/test/integration/Orders/Order.marginValidation.test.ts b/markets/perps-market/test/integration/Orders/Order.marginValidation.test.ts index f615031dcb..ce22719c69 100644 --- a/markets/perps-market/test/integration/Orders/Order.marginValidation.test.ts +++ b/markets/perps-market/test/integration/Orders/Order.marginValidation.test.ts @@ -82,7 +82,7 @@ describe('Orders - margin validation', () => { describe('openPosition 1 failure', () => { let orderFees: ethers.BigNumber; before('get order fees', async () => { - orderFees = await systems().PerpsMarket.computeOrderFees(51, 3); + [orderFees] = await systems().PerpsMarket.computeOrderFees(51, 3); }); it('reverts if not enough margin', async () => { @@ -98,6 +98,15 @@ describe('Orders - margin validation', () => { wei(10_000) ); + const totalRequiredMargin = initialMargin + .add(getMaxLiquidationReward(liquidationMargin, wei(100), wei(500))) + .add(orderFees); + + assertBn.equal( + await systems().PerpsMarket.requiredMarginForOrder(2, 51, bn(3)), + totalRequiredMargin.toBN() + ); + await assertRevert( systems() .PerpsMarket.connect(trader1()) @@ -110,10 +119,7 @@ describe('Orders - margin validation', () => { referrer: ethers.constants.AddressZero, trackingCode: ethers.constants.HashZero, }), - `InsufficientMargin("${bn(100)}", "${initialMargin - .add(getMaxLiquidationReward(liquidationMargin, wei(100), wei(500))) - .add(orderFees) - .toString(18, true)}")` + `InsufficientMargin("${bn(100)}", "${totalRequiredMargin.toString(18, true)}")` ); }); }); @@ -149,7 +155,7 @@ describe('Orders - margin validation', () => { describe('openPosition 2 failure', () => { let orderFees: ethers.BigNumber; before('get order fees', async () => { - orderFees = await systems().PerpsMarket.computeOrderFees(50, 5); + [orderFees] = await systems().PerpsMarket.computeOrderFees(50, 5); }); it('reverts if not enough margin', async () => { @@ -186,6 +192,11 @@ describe('Orders - margin validation', () => { .add(liqReward) .add(orderFees); + assertBn.equal( + await systems().PerpsMarket.requiredMarginForOrder(2, 50, bn(5)), + totalRequiredMargin.toBN() + ); + await assertRevert( systems() .PerpsMarket.connect(trader1()) @@ -233,7 +244,7 @@ describe('Orders - margin validation', () => { describe('modify position', () => { let orderFees: ethers.BigNumber; before('get order fees', async () => { - orderFees = await systems().PerpsMarket.computeOrderFees(50, 5); + [orderFees] = await systems().PerpsMarket.computeOrderFees(50, 5); }); it('reverts if not enough margin', async () => { @@ -270,6 +281,11 @@ describe('Orders - margin validation', () => { .add(liqReward) .add(orderFees); + assertBn.equal( + await systems().PerpsMarket.requiredMarginForOrder(2, 50, bn(5)), + totalRequiredMargin.toBN() + ); + await assertRevert( systems() .PerpsMarket.connect(trader1()) diff --git a/markets/perps-market/test/integration/Orders/GetOrderFees.test.ts b/markets/perps-market/test/integration/helpers/maxSize.ts similarity index 100% rename from markets/perps-market/test/integration/Orders/GetOrderFees.test.ts rename to markets/perps-market/test/integration/helpers/maxSize.ts From b0e1a5129e5b13d2ae8e1f6f42d96f0191f6385e Mon Sep 17 00:00:00 2001 From: Leonardo Massazza Date: Sat, 12 Aug 2023 04:40:37 +0100 Subject: [PATCH 47/63] Add order expired event (#1767) --- .../interfaces/IAsyncOrderModule.sol | 18 +++++ .../contracts/modules/AsyncOrderModule.sol | 21 +++++- .../contracts/storage/AsyncOrder.sol | 16 +---- .../Orders/OffchainAsyncOrder.commit.test.ts | 71 +++++++++++++++++++ 4 files changed, 110 insertions(+), 16 deletions(-) diff --git a/markets/perps-market/contracts/interfaces/IAsyncOrderModule.sol b/markets/perps-market/contracts/interfaces/IAsyncOrderModule.sol index b4fbc494ad..b8770cedaf 100644 --- a/markets/perps-market/contracts/interfaces/IAsyncOrderModule.sol +++ b/markets/perps-market/contracts/interfaces/IAsyncOrderModule.sol @@ -32,6 +32,24 @@ interface IAsyncOrderModule { address sender ); + /** + * @notice Gets fired when a new order is committed while a previous one was expired. + * @param marketId Id of the market used for the trade. + * @param accountId Id of the account used for the trade. + * @param sizeDelta requested change in size of the order sent by the user. + * @param acceptablePrice maximum or minimum, depending on the sizeDelta direction, accepted price to settle the order, set by the user. + * @param settlementTime Time at which the order can be settled. + * @param trackingCode Optional code for integrator tracking purposes. + */ + event PreviousOrderExpired( + uint128 indexed marketId, + uint128 indexed accountId, + int128 sizeDelta, + uint256 acceptablePrice, + uint256 settlementTime, + bytes32 indexed trackingCode + ); + /** * @notice Commit an async order via this function * @param commitment Order commitment data (see AsyncOrder.OrderCommitmentRequest struct). diff --git a/markets/perps-market/contracts/modules/AsyncOrderModule.sol b/markets/perps-market/contracts/modules/AsyncOrderModule.sol index 18b2296d4c..c855acb6bd 100644 --- a/markets/perps-market/contracts/modules/AsyncOrderModule.sol +++ b/markets/perps-market/contracts/modules/AsyncOrderModule.sol @@ -55,7 +55,26 @@ contract AsyncOrderModule is IAsyncOrderModule { SettlementStrategy.Data storage strategy = PerpsMarketConfiguration .loadValidSettlementStrategy(commitment.marketId, commitment.settlementStrategyId); - AsyncOrder.Data storage order = AsyncOrder.createValid(commitment, strategy); + // pull order from storage and check if it is valid (not pending unexpired order) + AsyncOrder.Data storage order = AsyncOrder.checkPendingOrder(commitment.accountId); + + // if order (previous) sizeDelta is not zero and didn't revert while checking, it means the previous order expired + if (order.request.sizeDelta != 0) { + // @notice not including the expiration time since it requires the previous settlement strategy to be loaded and enabled, otherwise loading it will revert and will prevent new orders to be committed + emit PreviousOrderExpired( + order.request.marketId, + order.request.accountId, + order.request.sizeDelta, + order.request.acceptablePrice, + order.settlementTime, + order.request.trackingCode + ); + } + + // Replace previous (or empty) order with the commitment request + order.settlementTime = block.timestamp + strategy.settlementDelay; + order.request = commitment; + (, uint feesAccrued, , ) = order.validateRequest( strategy, PerpsPrice.getCurrentPrice(commitment.marketId) diff --git a/markets/perps-market/contracts/storage/AsyncOrder.sol b/markets/perps-market/contracts/storage/AsyncOrder.sol index 463703fba4..ab9b84ccfb 100644 --- a/markets/perps-market/contracts/storage/AsyncOrder.sol +++ b/markets/perps-market/contracts/storage/AsyncOrder.sol @@ -151,23 +151,9 @@ library AsyncOrder { checkWithinSettlementWindow(order, strategy); } - /** - * @dev Reverts if the order does not belongs to the market or not exists. Otherwise, returns the order. - * @dev non-existent order is considered an order with sizeDelta == 0. - */ - function createValid( - OrderCommitmentRequest memory newRequest, - SettlementStrategy.Data storage strategy - ) internal returns (Data storage order) { - order = checkPendingOrder(newRequest.accountId); - - order.settlementTime = block.timestamp + strategy.settlementDelay; - order.request = newRequest; - } - /** * @dev Reverts if there is a pending order. - * @dev A pending order is one that has a sizeDelta or isn't expired yet. + * @dev A pending order is one that has a sizeDelta and isn't expired yet. */ function checkPendingOrder(uint128 accountId) internal view returns (Data storage order) { order = load(accountId); diff --git a/markets/perps-market/test/integration/Orders/OffchainAsyncOrder.commit.test.ts b/markets/perps-market/test/integration/Orders/OffchainAsyncOrder.commit.test.ts index 2ac5307c6d..aa6b59cc4f 100644 --- a/markets/perps-market/test/integration/Orders/OffchainAsyncOrder.commit.test.ts +++ b/markets/perps-market/test/integration/Orders/OffchainAsyncOrder.commit.test.ts @@ -229,6 +229,8 @@ describe('Commit Offchain Async Order test', () => { startTime = await getTxTime(provider(), tx); }); + const restoreToSettle = snapshotCheckpoint(provider); + it('emit event', async () => { await assertEvent( tx, @@ -270,6 +272,7 @@ describe('Commit Offchain Async Order test', () => { }); describe('can settle order', () => { + before(restoreToSettle); before('settle', async () => { const settlementTime = startTime + DEFAULT_SETTLEMENT_STRATEGY.settlementDelay + 1; await fastForwardTo(settlementTime, provider()); @@ -330,6 +333,74 @@ describe('Commit Offchain Async Order test', () => { }); }); }); + + describe('when order expired', () => { + let expirationTime: number; + + before('move after expiration', async () => { + expirationTime = + startTime + + DEFAULT_SETTLEMENT_STRATEGY.settlementDelay + + DEFAULT_SETTLEMENT_STRATEGY.settlementWindowDuration + + 1; + await fastForwardTo(expirationTime, provider()); + }); + + it('reverts if attempt to settle', async () => { + await assertRevert( + settleOrder({ + systems, + keeper: keeper(), + accountId: 2, + feedId: DEFAULT_SETTLEMENT_STRATEGY.feedId, + settlementTime: expirationTime, + offChainPrice: 1000, + }), + 'SettlementWindowExpired' + ); + }); + + describe('can commit another order after expiration', () => { + let tx: ethers.ContractTransaction; + let secondOrderStartTime: number; + before('commit the order', async () => { + tx = await systems() + .PerpsMarket.connect(trader1()) + .commitOrder({ + marketId: ethMarketId, + accountId: 2, + sizeDelta: bn(1), + settlementStrategyId: 0, + acceptablePrice: bn(1050), // 5% slippage + referrer: ethers.constants.AddressZero, + trackingCode: ethers.constants.HashZero, + }); + secondOrderStartTime = await getTxTime(provider(), tx); + }); + + it('emit the order commited event', async () => { + await assertEvent( + tx, + `OrderCommitted(${ethMarketId}, 2, ${DEFAULT_SETTLEMENT_STRATEGY.strategyType}, ${bn( + 1 + )}, ${bn(1050)}, ${secondOrderStartTime + 5}, ${secondOrderStartTime + 5 + 120}, "${ + ethers.constants.HashZero + }", "${await trader1().getAddress()}")`, + systems().PerpsMarket + ); + }); + + it('emit the order expired event', async () => { + await assertEvent( + tx, + `PreviousOrderExpired(${ethMarketId}, 2, ${bn(1)}, ${bn(1050)}, ${startTime + 5}, "${ + ethers.constants.HashZero + }")`, + systems().PerpsMarket + ); + }); + }); + }); }); } }); From 92f531faa5740bfdf4ddfdbd5fab7cb98c3128f5 Mon Sep 17 00:00:00 2001 From: Noisekit Date: Mon, 14 Aug 2023 17:07:49 +0800 Subject: [PATCH 48/63] Fix Infura URL for optimism mainnet (#1763) --- utils/common-config/hardhat.config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/common-config/hardhat.config.ts b/utils/common-config/hardhat.config.ts index c35e73ae43..7db95c17a8 100644 --- a/utils/common-config/hardhat.config.ts +++ b/utils/common-config/hardhat.config.ts @@ -59,7 +59,7 @@ const config = { ['optimistic-mainnet']: { url: process.env.NETWORK_ENDPOINT || - `https://optimism.infura.io/v3/${process.env.INFURA_API_KEY}`, + `https://optimism-mainnet.infura.io/v3/${process.env.INFURA_API_KEY}`, accounts: process.env.DEPLOYER_PRIVATE_KEY ? [process.env.DEPLOYER_PRIVATE_KEY] : [], chainId: 10, }, From 06f070b67761459b74c5e97f27bc43f1088b7abd Mon Sep 17 00:00:00 2001 From: Noisekit Date: Mon, 14 Aug 2023 21:08:10 +0800 Subject: [PATCH 49/63] Proxy change check (#1755) * Simulate release for each package and fail if Initial Proxy has been redeployed * Disable workspaces that are not yet ready for release check --- .github/workflows/simulate-release.yml | 87 ++++++++++++++++++++------ 1 file changed, 69 insertions(+), 18 deletions(-) diff --git a/.github/workflows/simulate-release.yml b/.github/workflows/simulate-release.yml index f08cd1b0cb..3902f49469 100644 --- a/.github/workflows/simulate-release.yml +++ b/.github/workflows/simulate-release.yml @@ -7,7 +7,7 @@ on: - "main" jobs: - test: + simulate-release: runs-on: ubuntu-latest env: CANNON_SETTINGS: ${{ secrets.CANNON_SETTINGS }} @@ -17,15 +17,51 @@ jobs: strategy: fail-fast: false matrix: - network: [goerli, optimistic-goerli] - project: [protocol/oracle-manager, protocol/synthetix] + workspace: [ + "@synthetixio/main", + "@synthetixio/oracle-manager", + # "@synthetixio/governance", TODO: enable after deployed + # "@synthetixio/legacy-market", TODO: enable after v2x is updated + "@synthetixio/spot-market", + # "@synthetixio/perps-market", TODO: enable after deployed + ] include: - - project: protocol/oracle-manager - cannonPackage: oracle-manager:latest + - workspace: "@synthetixio/main" + cannonPackage: "synthetix" impersonate: "0x48914229deDd5A9922f44441ffCCfC2Cb7856Ee9" - - project: protocol/synthetix - cannonPackage: synthetix:latest + proxy: "InitialCoreProxy" + chains: "mainnet optimistic-mainnet goerli optimistic-goerli" + + - workspace: "@synthetixio/oracle-manager" + cannonPackage: "oracle-manager" + impersonate: "0x48914229deDd5A9922f44441ffCCfC2Cb7856Ee9" + proxy: "InitialProxy" + chains: "mainnet optimistic-mainnet goerli optimistic-goerli" + + # - workspace: "@synthetixio/governance" + # cannonPackage: "governance" + # impersonate: "0x48914229deDd5A9922f44441ffCCfC2Cb7856Ee9" + # proxy: "InitialProxy" + # chains: "mainnet optimistic-mainnet goerli optimistic-goerli" + + # - workspace: "@synthetixio/legacy-market" + # cannonPackage: "synthetix-legacy-market" + # impersonate: "0x48914229deDd5A9922f44441ffCCfC2Cb7856Ee9" + # proxy: "InitialProxy" + # chains: "mainnet optimistic-mainnet goerli optimistic-goerli" + + - workspace: "@synthetixio/spot-market" + cannonPackage: "synthetix-spot-market" impersonate: "0x48914229deDd5A9922f44441ffCCfC2Cb7856Ee9" + proxy: "InitialProxy" + chains: "mainnet optimistic-mainnet goerli optimistic-goerli" + + # - workspace: "@synthetixio/perps-market" + # cannonPackage: "synthetix-perps-market" + # impersonate: "0x48914229deDd5A9922f44441ffCCfC2Cb7856Ee9" + # proxy: "InitialProxy" + # chains: "mainnet optimistic-mainnet goerli optimistic-goerli" + steps: - name: Install Foundry (Cannon) uses: foundry-rs/foundry-toolchain@v1 @@ -35,19 +71,34 @@ jobs: - uses: actions/checkout@v3 - uses: actions/setup-node@v3 with: - node-version: "18.16.0" + node-version: "16.20.1" cache: "yarn" - uses: ibnesayeed/setup-ipfs@92d412e0dad36c06ffab50733e9c624896a0964f with: run_daemon: true - run: yarn install --immutable --immutable-cache - - run: yarn build - - run: | - set -o pipefail - cd ${{ matrix.project }} - yarn hardhat cannon:build --upgrade-from ${{ matrix.cannonPackage }} \ - --network ${{ matrix.network }} --dry-run \ - --impersonate ${{ matrix.impersonate}} | tee deployment.txt - # verify that a new proxy has not been deployed, we cannot edit the proxy - # this is kind of hacky but sufficient for the time being - - run: '! grep "exec: contract.InitialProxy\|exec: contract.InitialCoreProxy" ${{ matrix.project }}/deployment.txt' + - run: yarn workspaces foreach --topological-dev --recursive --verbose --from ${{ matrix.workspace }} run build:ts + - name: "Simulate release of '${{ matrix.cannonPackage }}' on chains '${{ matrix.chains }}'" + run: | + CHAINS="${{ matrix.chains }}" + WORKSPACE="${{ matrix.workspace }}" + for CHAIN in $CHAINS; do + echo + echo + echo + echo "...Checking $WORKSPACE on $CHAIN" + + yarn workspace ${{ matrix.workspace }} exec \ + hardhat cannon:build \ + --dry-run \ + --network $CHAIN \ + --upgrade-from ${{ matrix.cannonPackage }}:latest \ + --impersonate ${{ matrix.impersonate }} | tee deployment.log + + grep 'Successfully built package ${{ matrix.cannonPackage }}' deployment.log + + if [ $(grep -c 'exec: contract.${{ matrix.proxy }}' deployment.log) -gt 0 ]; then + echo "Proxy ${{ matrix.proxy }} was modified" + exit 1 + fi + done From 08fd1fe5f0eb68c5395e8a02c05a2001abf971f8 Mon Sep 17 00:00:00 2001 From: Leonardo Massazza Date: Mon, 14 Aug 2023 15:20:27 +0100 Subject: [PATCH 50/63] Add missing docs on interfaces and modules (#1745) * Add missing docs on interfaces and modules * Update markets/perps-market/contracts/interfaces/IPerpsMarketFactoryModule.sol Co-authored-by: troy (troyb.eth) * pr review -> size in `units of native asset` * docgen --------- Co-authored-by: troy (troyb.eth) --- docs/Contracts.md | 164 +++++++++++++++++- .../interfaces/ILiquidationModule.sol | 28 +++ .../contracts/interfaces/IMarketEvents.sol | 3 + .../interfaces/IPerpsMarketFactoryModule.sol | 34 ++++ .../interfaces/IPerpsMarketModule.sol | 56 +++++- .../contracts/mocks/FeeCollectorMock.sol | 3 + .../perps-market/contracts/mocks/MockPyth.sol | 2 +- .../contracts/modules/AsyncOrderModule.sol | 2 +- .../modules/AsyncOrderSettlementModule.sol | 4 + .../contracts/modules/LiquidationModule.sol | 16 ++ .../modules/PerpsMarketFactoryModule.sol | 15 ++ .../contracts/modules/PerpsMarketModule.sol | 31 ++++ markets/perps-market/docs/index.md | 164 +++++++++++++++++- 13 files changed, 517 insertions(+), 5 deletions(-) diff --git a/docs/Contracts.md b/docs/Contracts.md index e37b0fc77d..909f6f220b 100644 --- a/docs/Contracts.md +++ b/docs/Contracts.md @@ -3830,7 +3830,7 @@ There is a synthetix v3 core system supply cap also set. If the current supply b #### computeOrderFees ```solidity - function computeOrderFees(uint128 marketId, int128 sizeDelta) external view returns (uint256 orderFees) + function computeOrderFees(uint128 marketId, int128 sizeDelta) external view returns (uint256 orderFees, uint256 fillPrice) ``` Simulates what the order fee would be for the given market with the specified size. @@ -3843,6 +3843,24 @@ There is a synthetix v3 core system supply cap also set. If the current supply b **Returns** * `orderFees` (*uint256*) - incurred fees. +* `fillPrice` (*uint256*) - price at which the order would be filled. +#### requiredMarginForOrder + + ```solidity + function requiredMarginForOrder(uint128 marketId, uint128 accountId, int128 sizeDelta) external view returns (uint256 requiredMargin) + ``` + + For a given market, account id, and a position size, returns the required total account margin for this order to succeed + + Useful for integrators to determine if an order will succeed or fail + +**Parameters** +* `marketId` (*uint128*) - id of the market. +* `accountId` (*uint128*) - id of the trader account. +* `sizeDelta` (*int128*) - size of position. + +**Returns** +* `requiredMargin` (*uint256*) - margin required for the order to succeed. #### OrderCommitted @@ -3863,6 +3881,22 @@ There is a synthetix v3 core system supply cap also set. If the current supply b * `trackingCode` (*bytes32*) - Optional code for integrator tracking purposes. * `sender` (*address*) - address of the sender of the order. Authorized to commit by account owner. +#### PreviousOrderExpired + + ```solidity + event PreviousOrderExpired(uint128 marketId, uint128 accountId, int128 sizeDelta, uint256 acceptablePrice, uint256 settlementTime, bytes32 trackingCode) + ``` + + Gets fired when a new order is committed while a previous one was expired. + +**Parameters** +* `marketId` (*uint128*) - Id of the market used for the trade. +* `accountId` (*uint128*) - Id of the account used for the trade. +* `sizeDelta` (*int128*) - requested change in size of the order sent by the user. +* `acceptablePrice` (*uint256*) - maximum or minimum, depending on the sizeDelta direction, accepted price to settle the order, set by the user. +* `settlementTime` (*uint256*) - Time at which the order can be settled. +* `trackingCode` (*bytes32*) - Optional code for integrator tracking purposes. + ### Async Order Settlement Module #### settle @@ -4147,24 +4181,50 @@ There is a synthetix v3 core system supply cap also set. If the current supply b function liquidate(uint128 accountId) external ``` + Liquidates an account. + + according to the current situation and account size it can be a partial or full liquidation. + +**Parameters** +* `accountId` (*uint128*) - Id of the account to liquidate. + #### liquidateFlagged ```solidity function liquidateFlagged() external ``` + Liquidates all flagged accounts. + #### PositionLiquidated ```solidity event PositionLiquidated(uint128 accountId, uint128 marketId, uint256 amountLiquidated, int128 currentPositionSize) ``` + Gets fired when an account position is liquidated . + +**Parameters** +* `accountId` (*uint128*) - Id of the account liquidated. +* `marketId` (*uint128*) - Id of the position's market. +* `amountLiquidated` (*uint256*) - amount liquidated. +* `currentPositionSize` (*int128*) - position size after liquidation. + #### AccountLiquidated ```solidity event AccountLiquidated(uint128 accountId, uint256 reward, bool fullLiquidation) ``` + Gets fired when an account is liquidated. + + this event is fired once per liquidation tx after the each position that can be liquidated at the time was liquidated. + +**Parameters** +* `accountId` (*uint128*) - Id of the account liquidated. +* `reward` (*uint256*) - total reward sent to liquidator. +* `fullLiquidation` (*bool*) - flag indicating if it was a partial or full liquidation. + ### Market Configuration Module #### addSettlementStrategy @@ -4625,24 +4685,49 @@ There is a synthetix v3 core system supply cap also set. If the current supply b function initializeFactory() external returns (uint128) ``` + Initializes the factory. + + this function should be called only once. + +**Returns** +* `[0]` (*uint128*) - globalPerpsMarketId Id of the global perps market id. #### setSynthetix ```solidity function setSynthetix(contract ISynthetixSystem synthetix) external ``` + Sets the synthetix system. + +**Parameters** +* `synthetix` (*contract ISynthetixSystem*) - address of the main synthetix proxy. + #### setSpotMarket ```solidity function setSpotMarket(contract ISpotMarketSystem spotMarket) external ``` + Sets the spot market system. + +**Parameters** +* `spotMarket` (*contract ISpotMarketSystem*) - address of the spot market proxy. + #### createMarket ```solidity function createMarket(uint128 requestedMarketId, string marketName, string marketSymbol) external returns (uint128) ``` + Creates a new market. + +**Parameters** +* `requestedMarketId` (*uint128*) - id of the market to create. +* `marketName` (*string*) - name of the market to create. +* `marketSymbol` (*string*) - symbol of the market to create. + +**Returns** +* `[0]` (*uint128*) - perpsMarketId Id of the created perps market. #### name ```solidity @@ -4687,12 +4772,24 @@ There is a synthetix v3 core system supply cap also set. If the current supply b event FactoryInitialized(uint128 globalPerpsMarketId) ``` + Gets fired when the factory is initialized. + +**Parameters** +* `globalPerpsMarketId` (*uint128*) - the new global perps market id. + #### MarketCreated ```solidity event MarketCreated(uint128 perpsMarketId, string marketName, string marketSymbol) ``` + Gets fired when a market is created. + +**Parameters** +* `perpsMarketId` (*uint128*) - the newly created perps market id. +* `marketName` (*string*) - the newly created perps market name. +* `marketSymbol` (*string*) - the newly created perps market symbol. + ### Perps Market Module #### metadata @@ -4701,48 +4798,107 @@ There is a synthetix v3 core system supply cap also set. If the current supply b function metadata(uint128 marketId) external view returns (string name, string symbol) ``` + Gets a market metadata. + +**Parameters** +* `marketId` (*uint128*) - Id of the market. + +**Returns** +* `name` (*string*) - Name of the market. +* `symbol` (*string*) - Symbol of the market. #### skew ```solidity function skew(uint128 marketId) external view returns (int256) ``` + Gets a market's skew. + +**Parameters** +* `marketId` (*uint128*) - Id of the market. + +**Returns** +* `[0]` (*int256*) - skew Skew of the market. #### size ```solidity function size(uint128 marketId) external view returns (uint256) ``` + Gets a market's size. + +**Parameters** +* `marketId` (*uint128*) - Id of the market. + +**Returns** +* `[0]` (*uint256*) - size Size of the market. #### maxOpenInterest ```solidity function maxOpenInterest(uint128 marketId) external view returns (uint256) ``` + Gets a market's max open interest. + +**Parameters** +* `marketId` (*uint128*) - Id of the market. + +**Returns** +* `[0]` (*uint256*) - maxOpenInterest Max open interest of the market. #### currentFundingRate ```solidity function currentFundingRate(uint128 marketId) external view returns (int256) ``` + Gets a market's current funding rate. + +**Parameters** +* `marketId` (*uint128*) - Id of the market. + +**Returns** +* `[0]` (*int256*) - currentFundingRate Current funding rate of the market. #### currentFundingVelocity ```solidity function currentFundingVelocity(uint128 marketId) external view returns (int256) ``` + Gets a market's current funding velocity. + +**Parameters** +* `marketId` (*uint128*) - Id of the market. + +**Returns** +* `[0]` (*int256*) - currentFundingVelocity Current funding velocity of the market. #### indexPrice ```solidity function indexPrice(uint128 marketId) external view returns (uint256) ``` + Gets a market's index price. + +**Parameters** +* `marketId` (*uint128*) - Id of the market. + +**Returns** +* `[0]` (*uint256*) - indexPrice Index price of the market. #### fillPrice ```solidity function fillPrice(uint128 marketId, int128 orderSize, uint256 price) external returns (uint256) ``` + Gets a market's fill price for a specific order size and index price. + +**Parameters** +* `marketId` (*uint128*) - Id of the market. +* `orderSize` (*int128*) - Order size. +* `price` (*uint256*) - Index price. + +**Returns** +* `[0]` (*uint256*) - price Fill price. #### getMarketSummary ```solidity @@ -4751,6 +4907,12 @@ There is a synthetix v3 core system supply cap also set. If the current supply b Given a marketId return a market's summary details in one call. +**Parameters** +* `marketId` (*uint128*) - Id of the market. + +**Returns** +* `summary` (*struct IPerpsMarketModule.MarketSummary*) - Market summary (see MarketSummary). + ## Governance - [Back to TOC](#smart-contracts) diff --git a/markets/perps-market/contracts/interfaces/ILiquidationModule.sol b/markets/perps-market/contracts/interfaces/ILiquidationModule.sol index 0dabb49e0d..efbee7f8a8 100644 --- a/markets/perps-market/contracts/interfaces/ILiquidationModule.sol +++ b/markets/perps-market/contracts/interfaces/ILiquidationModule.sol @@ -1,9 +1,22 @@ //SPDX-License-Identifier: MIT pragma solidity >=0.8.11 <0.9.0; +/** + * @title Liquidation module + */ interface ILiquidationModule { + /** + * @notice Thrown when attempting to liquidate an account not elegible for liquidation + */ error NotEligibleForLiquidation(uint128 accountId); + /** + * @notice Gets fired when an account position is liquidated . + * @param marketId Id of the position's market. + * @param accountId Id of the account liquidated. + * @param amountLiquidated amount liquidated. + * @param currentPositionSize position size after liquidation. + */ event PositionLiquidated( uint128 indexed accountId, uint128 indexed marketId, @@ -11,9 +24,24 @@ interface ILiquidationModule { int128 currentPositionSize ); + /** + * @notice Gets fired when an account is liquidated. + * @dev this event is fired once per liquidation tx after the each position that can be liquidated at the time was liquidated. + * @param accountId Id of the account liquidated. + * @param reward total reward sent to liquidator. + * @param fullLiquidation flag indicating if it was a partial or full liquidation. + */ event AccountLiquidated(uint128 indexed accountId, uint256 reward, bool fullLiquidation); + /** + * @notice Liquidates an account. + * @dev according to the current situation and account size it can be a partial or full liquidation. + * @param accountId Id of the account to liquidate. + */ function liquidate(uint128 accountId) external; + /** + * @notice Liquidates all flagged accounts. + */ function liquidateFlagged() external; } diff --git a/markets/perps-market/contracts/interfaces/IMarketEvents.sol b/markets/perps-market/contracts/interfaces/IMarketEvents.sol index adf02e7144..862dfd43a1 100644 --- a/markets/perps-market/contracts/interfaces/IMarketEvents.sol +++ b/markets/perps-market/contracts/interfaces/IMarketEvents.sol @@ -1,6 +1,9 @@ //SPDX-License-Identifier: MIT pragma solidity >=0.8.11 <0.9.0; +/** + * @title Market events used on several places in the system. + */ interface IMarketEvents { /** * @notice Gets fired when the size of a market is updated by new orders or liquidations. diff --git a/markets/perps-market/contracts/interfaces/IPerpsMarketFactoryModule.sol b/markets/perps-market/contracts/interfaces/IPerpsMarketFactoryModule.sol index c35ec33f9d..8c86bd45f3 100644 --- a/markets/perps-market/contracts/interfaces/IPerpsMarketFactoryModule.sol +++ b/markets/perps-market/contracts/interfaces/IPerpsMarketFactoryModule.sol @@ -5,16 +5,50 @@ import {IMarket} from "@synthetixio/main/contracts/interfaces/external/IMarket.s import {ISynthetixSystem} from "./external/ISynthetixSystem.sol"; import {ISpotMarketSystem} from "./external/ISpotMarketSystem.sol"; +/** + * @title Perps Market Factory module + */ interface IPerpsMarketFactoryModule is IMarket { + /** + * @notice Gets fired when the factory is initialized. + * @param globalPerpsMarketId the new global perps market id. + */ event FactoryInitialized(uint128 globalPerpsMarketId); + + /** + * @notice Gets fired when a market is created. + * @param perpsMarketId the newly created perps market id. + * @param marketName the newly created perps market name. + * @param marketSymbol the newly created perps market symbol. + */ event MarketCreated(uint128 indexed perpsMarketId, string marketName, string marketSymbol); + /** + * @notice Initializes the factory. + * @dev this function should be called only once. + * @return globalPerpsMarketId Id of the global perps market id. + */ function initializeFactory() external returns (uint128); + /** + * @notice Sets the synthetix system. + * @param synthetix address of the main synthetix proxy. + */ function setSynthetix(ISynthetixSystem synthetix) external; + /** + * @notice Sets the spot market system. + * @param spotMarket address of the spot market proxy. + */ function setSpotMarket(ISpotMarketSystem spotMarket) external; + /** + * @notice Creates a new market. + * @param requestedMarketId id of the market to create. + * @param marketName name of the market to create. + * @param marketSymbol symbol of the market to create. + * @return perpsMarketId Id of the created perps market. + */ function createMarket( uint128 requestedMarketId, string memory marketName, diff --git a/markets/perps-market/contracts/interfaces/IPerpsMarketModule.sol b/markets/perps-market/contracts/interfaces/IPerpsMarketModule.sol index c50666862d..182b8b914e 100644 --- a/markets/perps-market/contracts/interfaces/IPerpsMarketModule.sol +++ b/markets/perps-market/contracts/interfaces/IPerpsMarketModule.sol @@ -5,35 +5,89 @@ pragma solidity >=0.8.11 <0.9.0; * @title Perps market module */ interface IPerpsMarketModule { + /** + * @notice Market Summary structured data. + */ struct MarketSummary { + // @dev Skew of the market in units of native asse int256 skew; + // @dev Size of the market in units of native asset uint256 size; + // @dev Max open interest of the market in units of native asset uint256 maxOpenInterest; + // @dev Current funding rate of the market int currentFundingRate; + // @dev Current funding velocity of the market int currentFundingVelocity; + // @dev Index price of the market uint indexPrice; } + /** + * @notice Gets a market metadata. + * @param marketId Id of the market. + * @return name Name of the market. + * @return symbol Symbol of the market. + */ function metadata( uint128 marketId ) external view returns (string memory name, string memory symbol); + /** + * @notice Gets a market's skew. + * @param marketId Id of the market. + * @return skew Skew of the market. + */ function skew(uint128 marketId) external view returns (int256); + /** + * @notice Gets a market's size. + * @param marketId Id of the market. + * @return size Size of the market. + */ function size(uint128 marketId) external view returns (uint256); + /** + * @notice Gets a market's max open interest. + * @param marketId Id of the market. + * @return maxOpenInterest Max open interest of the market. + */ function maxOpenInterest(uint128 marketId) external view returns (uint256); + /** + * @notice Gets a market's current funding rate. + * @param marketId Id of the market. + * @return currentFundingRate Current funding rate of the market. + */ function currentFundingRate(uint128 marketId) external view returns (int); + /** + * @notice Gets a market's current funding velocity. + * @param marketId Id of the market. + * @return currentFundingVelocity Current funding velocity of the market. + */ function currentFundingVelocity(uint128 marketId) external view returns (int); + /** + * @notice Gets a market's index price. + * @param marketId Id of the market. + * @return indexPrice Index price of the market. + */ function indexPrice(uint128 marketId) external view returns (uint); + /** + * @notice Gets a market's fill price for a specific order size and index price. + * @param marketId Id of the market. + * @param orderSize Order size. + * @param price Index price. + * @return price Fill price. + */ function fillPrice(uint128 marketId, int128 orderSize, uint price) external returns (uint); /** - * @dev Given a marketId return a market's summary details in one call. + * @notice Given a marketId return a market's summary details in one call. + * @param marketId Id of the market. + * @return summary Market summary (see MarketSummary). */ function getMarketSummary( uint128 marketId diff --git a/markets/perps-market/contracts/mocks/FeeCollectorMock.sol b/markets/perps-market/contracts/mocks/FeeCollectorMock.sol index 545e2b3faf..d48ac491f7 100644 --- a/markets/perps-market/contracts/mocks/FeeCollectorMock.sol +++ b/markets/perps-market/contracts/mocks/FeeCollectorMock.sol @@ -3,6 +3,9 @@ pragma solidity >=0.8.11 <0.9.0; import "../interfaces/external/IFeeCollector.sol"; +/** + * @title Mock Fee Collector. + */ contract FeeCollectorMock is IFeeCollector { uint internal feeRatioD18; diff --git a/markets/perps-market/contracts/mocks/MockPyth.sol b/markets/perps-market/contracts/mocks/MockPyth.sol index fcd59c605a..dc0e540d29 100644 --- a/markets/perps-market/contracts/mocks/MockPyth.sol +++ b/markets/perps-market/contracts/mocks/MockPyth.sol @@ -4,7 +4,7 @@ pragma solidity >=0.8.11 <0.9.0; import {MockPyth as BaseMockPyth} from "@synthetixio/oracle-manager/contracts/mocks/pyth/MockPyth.sol"; /** - * @title Module for connecting to other systems. + * @title Mocked Pyth. * See oracle-manager/../MockPyth */ contract MockPyth is BaseMockPyth { diff --git a/markets/perps-market/contracts/modules/AsyncOrderModule.sol b/markets/perps-market/contracts/modules/AsyncOrderModule.sol index c855acb6bd..5375b88e34 100644 --- a/markets/perps-market/contracts/modules/AsyncOrderModule.sol +++ b/markets/perps-market/contracts/modules/AsyncOrderModule.sol @@ -16,7 +16,7 @@ import {PerpsMarketConfiguration} from "../storage/PerpsMarketConfiguration.sol" import {SettlementStrategy} from "../storage/SettlementStrategy.sol"; /** - * @title Module for committing and settling async orders. + * @title Module for committing async orders. * @dev See IAsyncOrderModule. */ contract AsyncOrderModule is IAsyncOrderModule { diff --git a/markets/perps-market/contracts/modules/AsyncOrderSettlementModule.sol b/markets/perps-market/contracts/modules/AsyncOrderSettlementModule.sol index 1b55d8ef69..002151bbf7 100644 --- a/markets/perps-market/contracts/modules/AsyncOrderSettlementModule.sol +++ b/markets/perps-market/contracts/modules/AsyncOrderSettlementModule.sol @@ -17,6 +17,10 @@ import {PerpsMarketFactory} from "../storage/PerpsMarketFactory.sol"; import {GlobalPerpsMarketConfiguration} from "../storage/GlobalPerpsMarketConfiguration.sol"; import {IMarketEvents} from "../interfaces/IMarketEvents.sol"; +/** + * @title Module for settling async orders. + * @dev See IAsyncOrderSettlementModule. + */ contract AsyncOrderSettlementModule is IAsyncOrderSettlementModule, IMarketEvents { using DecimalMath for int256; using DecimalMath for uint256; diff --git a/markets/perps-market/contracts/modules/LiquidationModule.sol b/markets/perps-market/contracts/modules/LiquidationModule.sol index 19a3a54e43..dba0ea3829 100644 --- a/markets/perps-market/contracts/modules/LiquidationModule.sol +++ b/markets/perps-market/contracts/modules/LiquidationModule.sol @@ -14,6 +14,10 @@ import {PerpsMarketConfiguration} from "../storage/PerpsMarketConfiguration.sol" import {GlobalPerpsMarket} from "../storage/GlobalPerpsMarket.sol"; import {IMarketEvents} from "../interfaces/IMarketEvents.sol"; +/** + * @title Module for liquidating accounts. + * @dev See ILiquidationModule. + */ contract LiquidationModule is ILiquidationModule, IMarketEvents { using DecimalMath for uint256; using SafeCastU256 for uint256; @@ -24,6 +28,9 @@ contract LiquidationModule is ILiquidationModule, IMarketEvents { using PerpsMarketFactory for PerpsMarketFactory.Data; using GlobalPerpsMarketConfiguration for GlobalPerpsMarketConfiguration.Data; + /** + * @inheritdoc ILiquidationModule + */ function liquidate(uint128 accountId) external override { SetUtil.UintSet storage liquidatableAccounts = GlobalPerpsMarket .load() @@ -43,6 +50,9 @@ contract LiquidationModule is ILiquidationModule, IMarketEvents { } } + /** + * @inheritdoc ILiquidationModule + */ function liquidateFlagged() external override { uint256[] memory liquidatableAccounts = GlobalPerpsMarket .load() @@ -55,6 +65,9 @@ contract LiquidationModule is ILiquidationModule, IMarketEvents { } } + /** + * @dev liquidates an account + */ function _liquidateAccount(PerpsAccount.Data storage account) internal { uint128 accountId = account.id; uint256[] memory openPositionMarketIds = account.openPositionMarketIds.values(); @@ -105,6 +118,9 @@ contract LiquidationModule is ILiquidationModule, IMarketEvents { emit AccountLiquidated(accountId, keeperLiquidationReward, accountFullyLiquidated); } + /** + * @dev process the accumulated liquidation rewards + */ function _processLiquidationRewards(uint256 totalRewards) private returns (uint256 reward) { if (totalRewards == 0) { return 0; diff --git a/markets/perps-market/contracts/modules/PerpsMarketFactoryModule.sol b/markets/perps-market/contracts/modules/PerpsMarketFactoryModule.sol index 1a7011c0b3..bc0492a723 100644 --- a/markets/perps-market/contracts/modules/PerpsMarketFactoryModule.sol +++ b/markets/perps-market/contracts/modules/PerpsMarketFactoryModule.sol @@ -51,12 +51,18 @@ contract PerpsMarketFactoryModule is IPerpsMarketFactoryModule { store.oracle = synthetix.getOracleManager(); } + /** + * @inheritdoc IPerpsMarketFactoryModule + */ function setSpotMarket(ISpotMarketSystem spotMarket) external override { OwnableStorage.onlyOwner(); PerpsMarketFactory.load().spotMarket = spotMarket; } + /** + * @inheritdoc IPerpsMarketFactoryModule + */ function initializeFactory() external override returns (uint128) { FeatureFlag.ensureAccessToFeature(_CREATE_MARKET_FEATURE_FLAG); OwnableStorage.onlyOwner(); @@ -99,6 +105,9 @@ contract PerpsMarketFactoryModule is IPerpsMarketFactoryModule { return requestedMarketId; } + /** + * @inheritdoc IMarket + */ // solc-ignore-next-line func-mutability function name(uint128 perpsMarketId) external view override returns (string memory) { // todo: set name on initialize? @@ -106,6 +115,9 @@ contract PerpsMarketFactoryModule is IPerpsMarketFactoryModule { return "Perps Market"; } + /** + * @inheritdoc IMarket + */ function reportedDebt(uint128 perpsMarketId) external view override returns (uint256) { PerpsMarketFactory.Data storage factory = PerpsMarketFactory.load(); @@ -131,6 +143,9 @@ contract PerpsMarketFactoryModule is IPerpsMarketFactoryModule { return 0; } + /** + * @inheritdoc IMarket + */ function minimumCredit(uint128 perpsMarketId) external view override returns (uint256) { PerpsMarketFactory.Data storage factory = PerpsMarketFactory.load(); diff --git a/markets/perps-market/contracts/modules/PerpsMarketModule.sol b/markets/perps-market/contracts/modules/PerpsMarketModule.sol index c8d60b6636..58b7285b29 100644 --- a/markets/perps-market/contracts/modules/PerpsMarketModule.sol +++ b/markets/perps-market/contracts/modules/PerpsMarketModule.sol @@ -7,10 +7,17 @@ import {PerpsPrice} from "../storage/PerpsPrice.sol"; import {AsyncOrder} from "../storage/AsyncOrder.sol"; import {IPerpsMarketModule} from "../interfaces/IPerpsMarketModule.sol"; +/** + * @title Module for getting perps market information. + * @dev See IPerpsMarketModule. + */ contract PerpsMarketModule is IPerpsMarketModule { using PerpsMarket for PerpsMarket.Data; using AsyncOrder for AsyncOrder.Data; + /** + * @inheritdoc IPerpsMarketModule + */ function metadata( uint128 marketId ) external view override returns (string memory name, string memory symbol) { @@ -18,30 +25,51 @@ contract PerpsMarketModule is IPerpsMarketModule { return (market.name, market.symbol); } + /** + * @inheritdoc IPerpsMarketModule + */ function skew(uint128 marketId) external view override returns (int256) { return PerpsMarket.load(marketId).skew; } + /** + * @inheritdoc IPerpsMarketModule + */ function size(uint128 marketId) external view override returns (uint256) { return PerpsMarket.load(marketId).size; } + /** + * @inheritdoc IPerpsMarketModule + */ function maxOpenInterest(uint128 marketId) external view override returns (uint256) { return PerpsMarketConfiguration.load(marketId).maxMarketSize; } + /** + * @inheritdoc IPerpsMarketModule + */ function currentFundingRate(uint128 marketId) external view override returns (int) { return PerpsMarket.load(marketId).currentFundingRate(); } + /** + * @inheritdoc IPerpsMarketModule + */ function currentFundingVelocity(uint128 marketId) external view override returns (int) { return PerpsMarket.load(marketId).currentFundingVelocity(); } + /** + * @inheritdoc IPerpsMarketModule + */ function indexPrice(uint128 marketId) external view override returns (uint) { return PerpsPrice.getCurrentPrice(marketId); } + /** + * @inheritdoc IPerpsMarketModule + */ function fillPrice( uint128 marketId, int128 orderSize, @@ -56,6 +84,9 @@ contract PerpsMarketModule is IPerpsMarketModule { ); } + /** + * @inheritdoc IPerpsMarketModule + */ function getMarketSummary( uint128 marketId ) external view override returns (MarketSummary memory summary) { diff --git a/markets/perps-market/docs/index.md b/markets/perps-market/docs/index.md index 8f1fdd6cc0..3cba695af6 100644 --- a/markets/perps-market/docs/index.md +++ b/markets/perps-market/docs/index.md @@ -30,7 +30,7 @@ #### computeOrderFees ```solidity - function computeOrderFees(uint128 marketId, int128 sizeDelta) external view returns (uint256 orderFees) + function computeOrderFees(uint128 marketId, int128 sizeDelta) external view returns (uint256 orderFees, uint256 fillPrice) ``` Simulates what the order fee would be for the given market with the specified size. @@ -43,6 +43,24 @@ **Returns** * `orderFees` (*uint256*) - incurred fees. +* `fillPrice` (*uint256*) - price at which the order would be filled. +#### requiredMarginForOrder + + ```solidity + function requiredMarginForOrder(uint128 marketId, uint128 accountId, int128 sizeDelta) external view returns (uint256 requiredMargin) + ``` + + For a given market, account id, and a position size, returns the required total account margin for this order to succeed + + Useful for integrators to determine if an order will succeed or fail + +**Parameters** +* `marketId` (*uint128*) - id of the market. +* `accountId` (*uint128*) - id of the trader account. +* `sizeDelta` (*int128*) - size of position. + +**Returns** +* `requiredMargin` (*uint256*) - margin required for the order to succeed. #### OrderCommitted @@ -63,6 +81,22 @@ * `trackingCode` (*bytes32*) - Optional code for integrator tracking purposes. * `sender` (*address*) - address of the sender of the order. Authorized to commit by account owner. +#### PreviousOrderExpired + + ```solidity + event PreviousOrderExpired(uint128 marketId, uint128 accountId, int128 sizeDelta, uint256 acceptablePrice, uint256 settlementTime, bytes32 trackingCode) + ``` + + Gets fired when a new order is committed while a previous one was expired. + +**Parameters** +* `marketId` (*uint128*) - Id of the market used for the trade. +* `accountId` (*uint128*) - Id of the account used for the trade. +* `sizeDelta` (*int128*) - requested change in size of the order sent by the user. +* `acceptablePrice` (*uint256*) - maximum or minimum, depending on the sizeDelta direction, accepted price to settle the order, set by the user. +* `settlementTime` (*uint256*) - Time at which the order can be settled. +* `trackingCode` (*bytes32*) - Optional code for integrator tracking purposes. + ### Async Order Settlement Module #### settle @@ -347,24 +381,50 @@ function liquidate(uint128 accountId) external ``` + Liquidates an account. + + according to the current situation and account size it can be a partial or full liquidation. + +**Parameters** +* `accountId` (*uint128*) - Id of the account to liquidate. + #### liquidateFlagged ```solidity function liquidateFlagged() external ``` + Liquidates all flagged accounts. + #### PositionLiquidated ```solidity event PositionLiquidated(uint128 accountId, uint128 marketId, uint256 amountLiquidated, int128 currentPositionSize) ``` + Gets fired when an account position is liquidated . + +**Parameters** +* `accountId` (*uint128*) - Id of the account liquidated. +* `marketId` (*uint128*) - Id of the position's market. +* `amountLiquidated` (*uint256*) - amount liquidated. +* `currentPositionSize` (*int128*) - position size after liquidation. + #### AccountLiquidated ```solidity event AccountLiquidated(uint128 accountId, uint256 reward, bool fullLiquidation) ``` + Gets fired when an account is liquidated. + + this event is fired once per liquidation tx after the each position that can be liquidated at the time was liquidated. + +**Parameters** +* `accountId` (*uint128*) - Id of the account liquidated. +* `reward` (*uint256*) - total reward sent to liquidator. +* `fullLiquidation` (*bool*) - flag indicating if it was a partial or full liquidation. + ### Market Configuration Module #### addSettlementStrategy @@ -825,24 +885,49 @@ function initializeFactory() external returns (uint128) ``` + Initializes the factory. + + this function should be called only once. + +**Returns** +* `[0]` (*uint128*) - globalPerpsMarketId Id of the global perps market id. #### setSynthetix ```solidity function setSynthetix(contract ISynthetixSystem synthetix) external ``` + Sets the synthetix system. + +**Parameters** +* `synthetix` (*contract ISynthetixSystem*) - address of the main synthetix proxy. + #### setSpotMarket ```solidity function setSpotMarket(contract ISpotMarketSystem spotMarket) external ``` + Sets the spot market system. + +**Parameters** +* `spotMarket` (*contract ISpotMarketSystem*) - address of the spot market proxy. + #### createMarket ```solidity function createMarket(uint128 requestedMarketId, string marketName, string marketSymbol) external returns (uint128) ``` + Creates a new market. + +**Parameters** +* `requestedMarketId` (*uint128*) - id of the market to create. +* `marketName` (*string*) - name of the market to create. +* `marketSymbol` (*string*) - symbol of the market to create. + +**Returns** +* `[0]` (*uint128*) - perpsMarketId Id of the created perps market. #### name ```solidity @@ -887,12 +972,24 @@ event FactoryInitialized(uint128 globalPerpsMarketId) ``` + Gets fired when the factory is initialized. + +**Parameters** +* `globalPerpsMarketId` (*uint128*) - the new global perps market id. + #### MarketCreated ```solidity event MarketCreated(uint128 perpsMarketId, string marketName, string marketSymbol) ``` + Gets fired when a market is created. + +**Parameters** +* `perpsMarketId` (*uint128*) - the newly created perps market id. +* `marketName` (*string*) - the newly created perps market name. +* `marketSymbol` (*string*) - the newly created perps market symbol. + ### Perps Market Module #### metadata @@ -901,48 +998,107 @@ function metadata(uint128 marketId) external view returns (string name, string symbol) ``` + Gets a market metadata. + +**Parameters** +* `marketId` (*uint128*) - Id of the market. + +**Returns** +* `name` (*string*) - Name of the market. +* `symbol` (*string*) - Symbol of the market. #### skew ```solidity function skew(uint128 marketId) external view returns (int256) ``` + Gets a market's skew. + +**Parameters** +* `marketId` (*uint128*) - Id of the market. + +**Returns** +* `[0]` (*int256*) - skew Skew of the market. #### size ```solidity function size(uint128 marketId) external view returns (uint256) ``` + Gets a market's size. + +**Parameters** +* `marketId` (*uint128*) - Id of the market. + +**Returns** +* `[0]` (*uint256*) - size Size of the market. #### maxOpenInterest ```solidity function maxOpenInterest(uint128 marketId) external view returns (uint256) ``` + Gets a market's max open interest. + +**Parameters** +* `marketId` (*uint128*) - Id of the market. + +**Returns** +* `[0]` (*uint256*) - maxOpenInterest Max open interest of the market. #### currentFundingRate ```solidity function currentFundingRate(uint128 marketId) external view returns (int256) ``` + Gets a market's current funding rate. + +**Parameters** +* `marketId` (*uint128*) - Id of the market. + +**Returns** +* `[0]` (*int256*) - currentFundingRate Current funding rate of the market. #### currentFundingVelocity ```solidity function currentFundingVelocity(uint128 marketId) external view returns (int256) ``` + Gets a market's current funding velocity. + +**Parameters** +* `marketId` (*uint128*) - Id of the market. + +**Returns** +* `[0]` (*int256*) - currentFundingVelocity Current funding velocity of the market. #### indexPrice ```solidity function indexPrice(uint128 marketId) external view returns (uint256) ``` + Gets a market's index price. + +**Parameters** +* `marketId` (*uint128*) - Id of the market. + +**Returns** +* `[0]` (*uint256*) - indexPrice Index price of the market. #### fillPrice ```solidity function fillPrice(uint128 marketId, int128 orderSize, uint256 price) external returns (uint256) ``` + Gets a market's fill price for a specific order size and index price. + +**Parameters** +* `marketId` (*uint128*) - Id of the market. +* `orderSize` (*int128*) - Order size. +* `price` (*uint256*) - Index price. + +**Returns** +* `[0]` (*uint256*) - price Fill price. #### getMarketSummary ```solidity @@ -951,3 +1107,9 @@ Given a marketId return a market's summary details in one call. +**Parameters** +* `marketId` (*uint128*) - Id of the market. + +**Returns** +* `summary` (*struct IPerpsMarketModule.MarketSummary*) - Market summary (see MarketSummary). + From 5e6e736597b5a7c972e4fbe3b61b1a51a44c0e55 Mon Sep 17 00:00:00 2001 From: Sunny Vempati <5723490+sunnyvempati@users.noreply.github.com> Date: Mon, 14 Aug 2023 10:55:54 -0500 Subject: [PATCH 51/63] rename perps market proxy (#1768) Co-authored-by: Peiman <25097709+Rickk137@users.noreply.github.com> --- markets/perps-market/cannonfile.toml | 6 ++--- .../contracts/storage/AsyncOrder.sol | 2 +- markets/perps-market/storage.dump.sol | 26 +++++++++++++------ 3 files changed, 22 insertions(+), 12 deletions(-) diff --git a/markets/perps-market/cannonfile.toml b/markets/perps-market/cannonfile.toml index 8ac92e657a..19e5a06062 100644 --- a/markets/perps-market/cannonfile.toml +++ b/markets/perps-market/cannonfile.toml @@ -138,9 +138,9 @@ args = [ depends = [ "invoke.upgrade_proxy" ] -factory.AccountProxy.abiOf = ["synthetix.AccountRouter"] -factory.AccountProxy.event = "AssociatedSystemSet" -factory.AccountProxy.arg = 2 +factory.PerpsAccountProxy.abiOf = ["synthetix.AccountRouter"] +factory.PerpsAccountProxy.event = "AssociatedSystemSet" +factory.PerpsAccountProxy.arg = 2 # add pool owner to feature flag allow list [invoke.addPerpsMarketToFeatureFlag] diff --git a/markets/perps-market/contracts/storage/AsyncOrder.sol b/markets/perps-market/contracts/storage/AsyncOrder.sol index ab9b84ccfb..3e1e2dbc42 100644 --- a/markets/perps-market/contracts/storage/AsyncOrder.sol +++ b/markets/perps-market/contracts/storage/AsyncOrder.sol @@ -62,7 +62,7 @@ library AsyncOrder { /** * @notice Thrown when fill price exceeds the acceptable price set at submission. */ - error AcceptablePriceExceeded(uint256 acceptablePrice, uint256 fillPrice); + error AcceptablePriceExceeded(uint256 fillPrice, uint256 acceptablePrice); /** * @notice Gets thrown when pending orders exist and attempts to modify collateral. diff --git a/markets/perps-market/storage.dump.sol b/markets/perps-market/storage.dump.sol index 5579446c2d..b1f6dc9c36 100644 --- a/markets/perps-market/storage.dump.sol +++ b/markets/perps-market/storage.dump.sol @@ -423,10 +423,16 @@ interface IAsyncOrderSettlementModule { int128 newPositionSize; int128 sizeDelta; int256 pnl; + int256 accruedFunding; uint256 pnlUint; uint256 amountToDeduct; uint256 settlementReward; - PerpsMarketFactory.Data factory; + uint256 fillPrice; + uint256 totalFees; + uint256 referralFees; + uint256 feeCollectorFees; + Position.Data newPosition; + PerpsMarket.MarketUpdateData updateData; } } @@ -471,13 +477,8 @@ contract PerpsMarketFactoryModule { // @custom:artifact contracts/storage/AsyncOrder.sol:AsyncOrder library AsyncOrder { struct Data { - uint128 accountId; - uint128 marketId; - int128 sizeDelta; - uint128 settlementStrategyId; uint256 settlementTime; - uint256 acceptablePrice; - bytes32 trackingCode; + OrderCommitmentRequest request; } struct OrderCommitmentRequest { uint128 marketId; @@ -486,12 +487,18 @@ library AsyncOrder { uint128 settlementStrategyId; uint256 acceptablePrice; bytes32 trackingCode; + address referrer; } struct SimulateDataRuntime { + int128 sizeDelta; + uint128 accountId; + uint128 marketId; uint fillPrice; uint orderFees; uint availableMargin; uint currentLiquidationMargin; + uint accumulatedLiquidationRewards; + uint currentLiquidationReward; int128 newPositionSize; uint newNotionalValue; int currentAvailableMargin; @@ -530,6 +537,8 @@ library GlobalPerpsMarket { library GlobalPerpsMarketConfiguration { bytes32 private constant _SLOT_GLOBAL_PERPS_MARKET_CONFIGURATION = keccak256(abi.encode("io.synthetix.perps-market.GlobalPerpsMarketConfiguration")); struct Data { + address feeCollector; + mapping(address => uint256) referrerShare; mapping(uint128 => uint) maxCollateralAmounts; uint128[] synthDeductionPriority; uint minLiquidationRewardUsd; @@ -608,12 +617,13 @@ library PerpsMarketConfiguration { uint256 maxFundingVelocity; uint256 skewScale; uint256 initialMarginRatioD18; - uint256 maintenanceMarginRatioD18; + uint256 maintenanceMarginScalarD18; uint256 lockedOiRatioD18; uint256 maxLiquidationLimitAccumulationMultiplier; uint256 maxSecondsInLiquidationWindow; uint256 liquidationRewardRatioD18; uint256 minimumPositionMargin; + uint256 minimumInitialMarginRatioD18; } function load(uint128 marketId) internal pure returns (Data storage store) { bytes32 s = keccak256(abi.encode("io.synthetix.perps-market.PerpsMarketConfiguration", marketId)); From 8695bd235336dfd00223bc1e069e2e2f7c681464 Mon Sep 17 00:00:00 2001 From: Peiman Date: Tue, 15 Aug 2023 20:54:05 +0330 Subject: [PATCH 52/63] feat: update mock external node --- protocol/oracle-manager/contracts/mocks/MockExternalNode.sol | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/protocol/oracle-manager/contracts/mocks/MockExternalNode.sol b/protocol/oracle-manager/contracts/mocks/MockExternalNode.sol index f428e7631f..536ec1a492 100644 --- a/protocol/oracle-manager/contracts/mocks/MockExternalNode.sol +++ b/protocol/oracle-manager/contracts/mocks/MockExternalNode.sol @@ -37,8 +37,6 @@ contract MockExternalNode is IExternalNode { function supportsInterface( bytes4 interfaceId ) public view virtual override(IERC165) returns (bool) { - return - interfaceId == type(IExternalNode).interfaceId || - interfaceId == this.supportsInterface.selector; + return true } } From d5cc1c2daf5b988de8be20fd3915b2933db75189 Mon Sep 17 00:00:00 2001 From: Peiman Date: Tue, 15 Aug 2023 20:58:05 +0330 Subject: [PATCH 53/63] fix: linting issue --- .../oracle-manager/contracts/mocks/MockExternalNode.sol | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/protocol/oracle-manager/contracts/mocks/MockExternalNode.sol b/protocol/oracle-manager/contracts/mocks/MockExternalNode.sol index 536ec1a492..bcc22d029a 100644 --- a/protocol/oracle-manager/contracts/mocks/MockExternalNode.sol +++ b/protocol/oracle-manager/contracts/mocks/MockExternalNode.sol @@ -34,9 +34,7 @@ contract MockExternalNode is IExternalNode { return nodeDefinition.nodeType == NodeDefinition.NodeType.EXTERNAL; } - function supportsInterface( - bytes4 interfaceId - ) public view virtual override(IERC165) returns (bool) { - return true + function supportsInterface(bytes4) public view virtual override(IERC165) returns (bool) { + return true; } } From 2fcff58c9a051c127433913afd619f4d4eb05644 Mon Sep 17 00:00:00 2001 From: butternutsquash Date: Tue, 15 Aug 2023 18:51:48 +0100 Subject: [PATCH 54/63] adding tests --- .../contracts/modules/core/IssueUSDModule.sol | 12 ++++++------ .../integration/modules/core/IssueUSDModule.test.ts | 5 ++++- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/protocol/synthetix/contracts/modules/core/IssueUSDModule.sol b/protocol/synthetix/contracts/modules/core/IssueUSDModule.sol index abc2967a7c..031e313cad 100644 --- a/protocol/synthetix/contracts/modules/core/IssueUSDModule.sol +++ b/protocol/synthetix/contracts/modules/core/IssueUSDModule.sol @@ -130,8 +130,6 @@ contract IssueUSDModule is IIssueUSDModule { FeatureFlag.ensureAccessToFeature(_BURN_FEATURE_FLAG); Pool.Data storage pool = Pool.load(poolId); - Account.Data storage account = Account.load(accountId); - // Retrieve current position debt int256 debt = pool.updateAccountDebt(collateralType, accountId); @@ -152,12 +150,14 @@ contract IssueUSDModule is IIssueUSDModule { amount = debt.toUint() + feeAmount; } + AssociatedSystem.Data storage usdToken = AssociatedSystem.load(_USD_TOKEN); + // Burn the stablecoins - AssociatedSystem.load(_USD_TOKEN).asToken().burn(msg.sender, amount); + usdToken.asToken().burn(address(this), amount); - account.collaterals[collateralType].increaseAvailableCollateral( - CollateralConfiguration.load(collateralType).convertTokenToSystemAmount(amount) - ); + Account.Data storage account = Account.load(accountId); + + account.collaterals[usdToken.getAddress()].decreaseAvailableCollateral(amount); if (feeAmount > 0 && feeAddress != address(0)) { AssociatedSystem.load(_USD_TOKEN).asToken().mint(feeAddress, feeAmount); diff --git a/protocol/synthetix/test/integration/modules/core/IssueUSDModule.test.ts b/protocol/synthetix/test/integration/modules/core/IssueUSDModule.test.ts index 6e0f12da87..bec05287d1 100644 --- a/protocol/synthetix/test/integration/modules/core/IssueUSDModule.test.ts +++ b/protocol/synthetix/test/integration/modules/core/IssueUSDModule.test.ts @@ -10,7 +10,7 @@ import { verifyChecksCollateralEnabled, verifyUsesFeatureFlag } from '../../veri const MARKET_FEATURE_FLAG = ethers.utils.formatBytes32String('registerMarket'); -describe('IssueUSDModule', function () { +describe.only('IssueUSDModule', function () { const { signers, systems, provider, accountId, poolId, depositAmount, collateralAddress } = bootstrapWithStakedPool(); @@ -293,6 +293,9 @@ describe('IssueUSDModule', function () { }); before('other account burn', async () => { + await systems() + .Core.connect(user1) + .deposit(accountId, await systems().Core.getUsdToken(), depositAmount.div(10)); await systems() .Core.connect(user2) .burnUsd(accountId, poolId, collateralAddress(), depositAmount.div(10)); From e9438899e3939f5cf15ad2c0621a4da1e245b4bd Mon Sep 17 00:00:00 2001 From: max Date: Wed, 16 Aug 2023 14:18:25 +0100 Subject: [PATCH 55/63] update tests --- protocol/synthetix/storage.dump.sol | 14 +++++-- .../modules/core/IssueUSDModule.test.ts | 41 +++++++++++++++++-- 2 files changed, 49 insertions(+), 6 deletions(-) diff --git a/protocol/synthetix/storage.dump.sol b/protocol/synthetix/storage.dump.sol index 6e27eedc82..5ea45a2efc 100644 --- a/protocol/synthetix/storage.dump.sol +++ b/protocol/synthetix/storage.dump.sol @@ -268,7 +268,6 @@ contract IssueUSDModule { bytes32 private constant _CONFIG_BURN_FEE_RATIO = "burnUsd_feeRatio"; bytes32 private constant _CONFIG_MINT_FEE_ADDRESS = "mintUsd_feeAddress"; bytes32 private constant _CONFIG_BURN_FEE_ADDRESS = "burnUsd_feeAddress"; - bytes32 private constant _CONFIG_TIMEOUT_BURN = "burnUsd_toAccount"; } // @custom:artifact contracts/modules/core/LiquidationModule.sol:LiquidationModule @@ -545,8 +544,7 @@ library Pool { uint64 __reserved1; uint64 __reserved2; uint64 __reserved3; - mapping(address => bool) collateralTypeDisabled; - mapping(address => uint256) issuanceRatioD18; + mapping(address => PoolCollateralConfiguration.Data) collateralConfigurations; } function load(uint128 id) internal pure returns (Data storage pool) { bytes32 s = keccak256(abi.encode("io.synthetix.synthetix.Pool", id)); @@ -556,6 +554,16 @@ library Pool { } } +// @custom:artifact contracts/storage/PoolCollateralConfiguration.sol:PoolCollateralConfiguration +library PoolCollateralConfiguration { + bytes32 private constant _SLOT = keccak256(abi.encode("io.synthetix.synthetix.PoolCollateralConfiguration")); + struct Data { + uint256 maxDepositD18; + bool collateralTypeDisabled; + uint256 issuanceRatioD18; + } +} + // @custom:artifact contracts/storage/RewardDistribution.sol:RewardDistribution library RewardDistribution { struct Data { diff --git a/protocol/synthetix/test/integration/modules/core/IssueUSDModule.test.ts b/protocol/synthetix/test/integration/modules/core/IssueUSDModule.test.ts index bec05287d1..201a228572 100644 --- a/protocol/synthetix/test/integration/modules/core/IssueUSDModule.test.ts +++ b/protocol/synthetix/test/integration/modules/core/IssueUSDModule.test.ts @@ -2,7 +2,7 @@ import assertBn from '@synthetixio/core-utils/utils/assertions/assert-bignumber' import assertRevert from '@synthetixio/core-utils/utils/assertions/assert-revert'; import assertEvent from '@synthetixio/core-utils/utils/assertions/assert-event'; import { snapshotCheckpoint } from '@synthetixio/core-utils/utils/mocha/snapshot'; -import { BigNumber, ethers } from 'ethers'; +import { BigNumber, constants, ethers } from 'ethers'; import hre from 'hardhat'; import { bn, bootstrapWithStakedPool } from '../../bootstrap'; import Permissions from '../../mixins/AccountRBACMixin.permissions'; @@ -10,7 +10,7 @@ import { verifyChecksCollateralEnabled, verifyUsesFeatureFlag } from '../../veri const MARKET_FEATURE_FLAG = ethers.utils.formatBytes32String('registerMarket'); -describe.only('IssueUSDModule', function () { +describe('IssueUSDModule', function () { const { signers, systems, provider, accountId, poolId, depositAmount, collateralAddress } = bootstrapWithStakedPool(); @@ -294,7 +294,21 @@ describe.only('IssueUSDModule', function () { before('other account burn', async () => { await systems() - .Core.connect(user1) + .Core.connect(owner) + .configureCollateral({ + tokenAddress: await systems().Core.getUsdToken(), + oracleNodeId: ethers.utils.formatBytes32String(''), + issuanceRatioD18: 200, + liquidationRatioD18: 100, + liquidationRewardD18: 0, + minDelegationD18: 0, + depositingEnabled: true, + }); + await systems() + .USD.connect(user2) + .approve(systems().Core.address, constants.MaxUint256.toString()); + await systems() + .Core.connect(user2) .deposit(accountId, await systems().Core.getUsdToken(), depositAmount.div(10)); await systems() .Core.connect(user2) @@ -326,6 +340,27 @@ describe.only('IssueUSDModule', function () { }); before('account partial burn debt', async () => { + await systems() + .Core.connect(owner) + .configureCollateral({ + tokenAddress: await systems().Core.getUsdToken(), + oracleNodeId: ethers.utils.formatBytes32String(''), + issuanceRatioD18: 200, + liquidationRatioD18: 100, + liquidationRewardD18: 0, + minDelegationD18: 0, + depositingEnabled: true, + }); + await systems() + .USD.connect(user1) + .approve(systems().Core.address, constants.MaxUint256.toString()); + await systems() + .Core.connect(user1) + .deposit( + accountId, + await systems().Core.getUsdToken(), + depositAmount.div(20).add(depositAmount.div(2000)) + ); // in order to burn all with the fee we need a bit more await systems() .Core.connect(user1) From e87ac34b0d5f194f41549561b6578edbda70217d Mon Sep 17 00:00:00 2001 From: max Date: Wed, 16 Aug 2023 14:20:34 +0100 Subject: [PATCH 56/63] Q-1 Macro --- .../synthetix/contracts/modules/core/RewardsManagerModule.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/protocol/synthetix/contracts/modules/core/RewardsManagerModule.sol b/protocol/synthetix/contracts/modules/core/RewardsManagerModule.sol index 6e7629d354..aa7be8912e 100644 --- a/protocol/synthetix/contracts/modules/core/RewardsManagerModule.sol +++ b/protocol/synthetix/contracts/modules/core/RewardsManagerModule.sol @@ -155,7 +155,7 @@ contract RewardsManagerModule is IRewardsManagerModule { Account.loadAccountAndValidatePermission(accountId, AccountRBAC._REWARDS_PERMISSION); Vault.Data storage vault = Pool.load(poolId).vaults[collateralType]; - bytes32 rewardId = keccak256(abi.encode(poolId, collateralType, distributor)); + bytes32 rewardId = _getRewardId(poolId, collateralType, distributor); if (address(vault.rewards[rewardId].distributor) != distributor) { revert ParameterError.InvalidParameter("invalid-params", "reward is not found"); From c644a5a00a5c631d5aa3e0ab0183f00804f6e5a5 Mon Sep 17 00:00:00 2001 From: max Date: Wed, 16 Aug 2023 14:21:27 +0100 Subject: [PATCH 57/63] Q-3 Macro --- .../synthetix/contracts/modules/core/RewardsManagerModule.sol | 4 ---- 1 file changed, 4 deletions(-) diff --git a/protocol/synthetix/contracts/modules/core/RewardsManagerModule.sol b/protocol/synthetix/contracts/modules/core/RewardsManagerModule.sol index aa7be8912e..f951f6d351 100644 --- a/protocol/synthetix/contracts/modules/core/RewardsManagerModule.sol +++ b/protocol/synthetix/contracts/modules/core/RewardsManagerModule.sol @@ -251,10 +251,6 @@ contract RewardsManagerModule is IRewardsManagerModule { rewardIds.remove(rewardId); - if (distributor == address(0)) { - revert ParameterError.InvalidParameter("distributor", "must be non-zero"); - } - RewardDistribution.Data storage reward = pool.vaults[collateralType].rewards[rewardId]; // ensure rewards emission is stopped (users can still come in to claim rewards after the fact) From dafd84e38d77b970d2a92e6fa974960ffa2440e7 Mon Sep 17 00:00:00 2001 From: max Date: Wed, 16 Aug 2023 14:22:03 +0100 Subject: [PATCH 58/63] Q-8 Macro --- .../contracts/modules/core/CollateralConfigurationModule.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/protocol/synthetix/contracts/modules/core/CollateralConfigurationModule.sol b/protocol/synthetix/contracts/modules/core/CollateralConfigurationModule.sol index 01c4ff13e6..53f537e6b1 100644 --- a/protocol/synthetix/contracts/modules/core/CollateralConfigurationModule.sol +++ b/protocol/synthetix/contracts/modules/core/CollateralConfigurationModule.sol @@ -61,7 +61,7 @@ contract CollateralConfigurationModule is ICollateralConfigurationModule { // solc-ignore-next-line func-mutability function getCollateralConfiguration( address collateralType - ) external view override returns (CollateralConfiguration.Data memory) { + ) external pure override returns (CollateralConfiguration.Data memory) { return CollateralConfiguration.load(collateralType); } From b7ce55e9addbe0f21042a3f9a2da61bdeee9b8af Mon Sep 17 00:00:00 2001 From: max Date: Wed, 16 Aug 2023 14:23:28 +0100 Subject: [PATCH 59/63] I-1 Macro --- protocol/synthetix/contracts/modules/core/AccountModule.sol | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/protocol/synthetix/contracts/modules/core/AccountModule.sol b/protocol/synthetix/contracts/modules/core/AccountModule.sol index 23aca84d99..866fe91d9a 100644 --- a/protocol/synthetix/contracts/modules/core/AccountModule.sol +++ b/protocol/synthetix/contracts/modules/core/AccountModule.sol @@ -81,9 +81,10 @@ contract AccountModule is IAccountModule { accountId = (type(uint128).max / 2) + systemAccountConfiguration.accountIdOffset; systemAccountConfiguration.accountIdOffset += 1; - accountTokenModule.safeMint(msg.sender, accountId, ""); Account.create(accountId, msg.sender); + accountTokenModule.safeMint(msg.sender, accountId, ""); + emit AccountCreated(accountId, msg.sender); } From ad5222473ad720280328849fbb9117a584baddf6 Mon Sep 17 00:00:00 2001 From: max Date: Wed, 16 Aug 2023 14:34:51 +0100 Subject: [PATCH 60/63] Spotmarket I-1 Macro --- .../interfaces/ISpotMarketFactoryModule.sol | 7 +++++++ .../modules/SpotMarketFactoryModule.sol | 18 ++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/markets/spot-market/contracts/interfaces/ISpotMarketFactoryModule.sol b/markets/spot-market/contracts/interfaces/ISpotMarketFactoryModule.sol index 4c48cfeae6..3fa3797873 100644 --- a/markets/spot-market/contracts/interfaces/ISpotMarketFactoryModule.sol +++ b/markets/spot-market/contracts/interfaces/ISpotMarketFactoryModule.sol @@ -176,6 +176,13 @@ interface ISpotMarketFactoryModule is IMarket { */ function renounceMarketNomination(uint128 synthMarketId) external; + /** + * @notice Allows the market owner to renounce his ownership. + * @dev Reverts if the caller is not the owner. + * @param synthMarketId synth market id value + */ + function renounceMarketOwnership(uint128 synthMarketId) external; + /** * @notice Returns market owner. * @param synthMarketId synth market id value diff --git a/markets/spot-market/contracts/modules/SpotMarketFactoryModule.sol b/markets/spot-market/contracts/modules/SpotMarketFactoryModule.sol index 2f4a0c95f5..79f8dd4249 100644 --- a/markets/spot-market/contracts/modules/SpotMarketFactoryModule.sol +++ b/markets/spot-market/contracts/modules/SpotMarketFactoryModule.sol @@ -235,6 +235,24 @@ contract SpotMarketFactoryModule is ISpotMarketFactoryModule, AssociatedSystemsM return spotMarketFactory.marketOwners[synthMarketId]; } + /** + * @inheritdoc ISpotMarketFactoryModule + */ + function renounceMarketOwnership(uint128 synthMarketId) external override { + SpotMarketFactory.Data storage spotMarketFactory = SpotMarketFactory.load(); + address currentOwner = spotMarketFactory.marketOwners[synthMarketId]; + if (msg.sender != currentOwner) { + revert SpotMarketFactory.OnlyMarketOwner(currentOwner, msg.sender); + } + + spotMarketFactory.marketOwners[synthMarketId] = address(0); + emit MarketOwnerChanged( + synthMarketId, + spotMarketFactory.marketOwners[synthMarketId], + address(0) + ); + } + /** * @dev See {IERC165-supportsInterface}. */ From e7833871c55cd5d0c8b7b54615e0d05f544f6616 Mon Sep 17 00:00:00 2001 From: max Date: Wed, 16 Aug 2023 15:38:16 +0100 Subject: [PATCH 61/63] M-3 removing payable --- .../synthetix/contracts/interfaces/IMulticallModule.sol | 4 ++-- .../synthetix/contracts/modules/core/MulticallModule.sol | 6 ++---- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/protocol/synthetix/contracts/interfaces/IMulticallModule.sol b/protocol/synthetix/contracts/interfaces/IMulticallModule.sol index 6760472dc4..6f7df8cd49 100644 --- a/protocol/synthetix/contracts/interfaces/IMulticallModule.sol +++ b/protocol/synthetix/contracts/interfaces/IMulticallModule.sol @@ -11,7 +11,7 @@ interface IMulticallModule { * @param data Array of calldata objects, one for each function that is to be called in the system. * @return results Array of each `delegatecall`'s response corresponding to the incoming calldata array. */ - function multicall(bytes[] calldata data) external payable returns (bytes[] memory results); + function multicall(bytes[] calldata data) external returns (bytes[] memory results); /** * @notice Similar to `multicall`, but allows for transactions to be executed @@ -24,7 +24,7 @@ interface IMulticallModule { /*function multicallThrough( address[] calldata to, bytes[] calldata data - ) external payable returns (bytes[] memory results); + ) external returns (bytes[] memory results); function getMessageSender() external view returns (address);*/ } diff --git a/protocol/synthetix/contracts/modules/core/MulticallModule.sol b/protocol/synthetix/contracts/modules/core/MulticallModule.sol index d258240d57..316b15c5dd 100644 --- a/protocol/synthetix/contracts/modules/core/MulticallModule.sol +++ b/protocol/synthetix/contracts/modules/core/MulticallModule.sol @@ -18,9 +18,7 @@ contract MulticallModule is IMulticallModule { /** * @inheritdoc IMulticallModule */ - function multicall( - bytes[] calldata data - ) public payable override returns (bytes[] memory results) { + function multicall(bytes[] calldata data) public override returns (bytes[] memory results) { results = new bytes[](data.length); for (uint256 i = 0; i < data.length; i++) { (bool success, bytes memory result) = address(this).delegatecall(data[i]); @@ -40,7 +38,7 @@ contract MulticallModule is IMulticallModule { /*function multicallThrough( address[] calldata to, bytes[] calldata data - ) public payable override returns (bytes[] memory results) { + ) public override returns (bytes[] memory results) { if (Config.read(_CONFIG_MESSAGE_SENDER, 0) != 0) { revert RecursiveMulticall(msg.sender); } From 5f27305ae6a08f38765106619629e2b48c9ebde8 Mon Sep 17 00:00:00 2001 From: David Vuong Date: Thu, 17 Aug 2023 02:47:12 +1000 Subject: [PATCH 62/63] SIP-335 allow approve amount 0 to revoke erc20 (#1742) * SIP-335 allow approve amount 0 to revoke erc20 * Reuse _checkZeroAddress in _checkZeroAddressOrAmount Addressed comments in PR #1742. --------- Co-authored-by: Sunny Vempati --- utils/core-contracts/contracts/token/ERC20.sol | 12 ++++++++---- .../test/contracts/token/ERC20.test.ts | 18 ++++++++++++++---- 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/utils/core-contracts/contracts/token/ERC20.sol b/utils/core-contracts/contracts/token/ERC20.sol index 9b903400f8..768b9bf9bf 100644 --- a/utils/core-contracts/contracts/token/ERC20.sol +++ b/utils/core-contracts/contracts/token/ERC20.sol @@ -158,7 +158,7 @@ contract ERC20 is IERC20 { } function _approve(address owner, address spender, uint256 amount) internal virtual { - _checkZeroAddressOrAmount(spender, amount); + _checkZeroAddress(spender); ERC20Storage.load().allowance[owner][spender] = amount; @@ -166,15 +166,19 @@ contract ERC20 is IERC20 { } function _checkZeroAddressOrAmount(address target, uint256 amount) private pure { - if (target == address(0)) { - revert ParameterError.InvalidParameter("target", "Zero address"); - } + _checkZeroAddress(target); if (amount == 0) { revert ParameterError.InvalidParameter("amount", "Zero amount"); } } + function _checkZeroAddress(address target) private pure { + if (target == address(0)) { + revert ParameterError.InvalidParameter("target", "Zero address"); + } + } + function _mint(address to, uint256 amount) internal virtual { _checkZeroAddressOrAmount(to, amount); diff --git a/utils/core-contracts/test/contracts/token/ERC20.test.ts b/utils/core-contracts/test/contracts/token/ERC20.test.ts index ee193d9314..b6e046a7ac 100644 --- a/utils/core-contracts/test/contracts/token/ERC20.test.ts +++ b/utils/core-contracts/test/contracts/token/ERC20.test.ts @@ -53,10 +53,6 @@ describe('ERC20', function () { ); // Zero amount - await assertRevert( - ERC20.approve(await user1.getAddress(), 0), - 'InvalidParameter("amount", "Zero amount")' - ); await assertRevert( ERC20.transfer(await user1.getAddress(), 0), 'InvalidParameter("amount", "Zero amount")' @@ -221,6 +217,20 @@ describe('ERC20', function () { assertBn.equal(evt.args.amount, approvalAmount); }); + describe('approve()', async function () { + it('revokes token when amount zero', async function () { + await ERC20.connect(user1).approve(await user2.getAddress(), BigNumber.from('0')); + assertBn.equal( + await ERC20.allowance(await user1.getAddress(), await user2.getAddress()), + '0' + ); + }); + + after('reset approval', async () => { + await ERC20.connect(user1).approve(await user2.getAddress(), approvalAmount); + }); + }); + describe('increaseAllowance()', async () => { it('reverts when overflowing', async () => { await assertRevert( From 082d2a7158febd2e5f8bdd08113eed943ceeb8d2 Mon Sep 17 00:00:00 2001 From: Peiman <25097709+Rickk137@users.noreply.github.com> Date: Wed, 16 Aug 2023 20:24:21 +0330 Subject: [PATCH 63/63] Sip-323 (#1729) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: upgrade token in AssociatedSystemsModule * fix test assert * fix: perps graph issue * feat: update core subgraph core proxy * leave symbol for now --------- Co-authored-by: Noah Litvin <335975+noahlitvin@users.noreply.github.com> Co-authored-by: Matías Co-authored-by: Matías Lescano Co-authored-by: Noisekit --- .../modules/core/USDTokenModule.test.ts | 2 +- .../modules/AssociatedSystemsModule.sol | 5 ++++- .../modules/AssociatedSystemsModule.test.ts | 17 +++++++++++++++++ 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/protocol/synthetix/test/integration/modules/core/USDTokenModule.test.ts b/protocol/synthetix/test/integration/modules/core/USDTokenModule.test.ts index 5955e1ab57..9eafa928e2 100644 --- a/protocol/synthetix/test/integration/modules/core/USDTokenModule.test.ts +++ b/protocol/synthetix/test/integration/modules/core/USDTokenModule.test.ts @@ -1,6 +1,6 @@ -import assert from 'assert/strict'; import assertBn from '@synthetixio/core-utils/src/utils/assertions/assert-bignumber'; import assertRevert from '@synthetixio/core-utils/utils/assertions/assert-revert'; +import assert from 'assert/strict'; import { ethers } from 'ethers'; import { bn, bootstrapWithStakedPool } from '../../bootstrap'; diff --git a/utils/core-modules/contracts/modules/AssociatedSystemsModule.sol b/utils/core-modules/contracts/modules/AssociatedSystemsModule.sol index 0106e765e9..162525f576 100644 --- a/utils/core-modules/contracts/modules/AssociatedSystemsModule.sol +++ b/utils/core-modules/contracts/modules/AssociatedSystemsModule.sol @@ -126,7 +126,10 @@ contract AssociatedSystemsModule is IAssociatedSystemsModule { AssociatedSystem.Data storage store = AssociatedSystem.load(id); if (store.proxy != address(0)) { - _upgradeToken(id, impl); + if (store.impl != impl) { + _upgradeToken(id, impl); + } + ITokenModule(store.proxy).initialize(name, symbol, decimals); } else { // create a new proxy and own it address proxy = address(new UUPSProxyWithOwner(impl, address(this))); diff --git a/utils/core-modules/test/contracts/modules/AssociatedSystemsModule.test.ts b/utils/core-modules/test/contracts/modules/AssociatedSystemsModule.test.ts index a9a602250d..3b11491527 100644 --- a/utils/core-modules/test/contracts/modules/AssociatedSystemsModule.test.ts +++ b/utils/core-modules/test/contracts/modules/AssociatedSystemsModule.test.ts @@ -156,6 +156,23 @@ describe('AssociatedSystemsModule', function () { assert.equal(await TokenModule.isInitialized(), false); }); + it('upgrade token with new name and symbol', async () => { + await AssociatedSystemsModule.initOrUpgradeToken( + registeredName, + 'A Token 2', + 'TOK2', + 18, + TokenModule.address + ); + }); + + it('the token has been successfully reinitlized', async function () { + assert.equal(await TokenModuleAssociated.isInitialized(), true); + assert.equal(await TokenModuleAssociated.name(), 'A Token 2'); + assert.equal(await TokenModuleAssociated.symbol(), 'TOK2'); + assert.equal(await TokenModuleAssociated.decimals(), 18); + }); + describe('when attempting to register a different kind', function () { before('prepare modules', async function () { await AssociatedSystemsModule.initOrUpgradeNft(

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 z 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