Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sip366 feedback - lock intent to delegate collateral #2244

Open
wants to merge 12 commits into
base: SIP-366-implementation
Choose a base branch
from
4 changes: 3 additions & 1 deletion markets/bfp-market/storage.dump.sol
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,8 @@ library AccountDelegationIntents {
SetUtil.UintSet intentsId;
mapping(bytes32 => SetUtil.UintSet) intentsByPair;
SetUtil.AddressSet delegatedCollaterals;
mapping(address => int256) netDelegatedAmountPerCollateral;
mapping(address => uint256) delegatedAmountPerCollateral;
mapping(address => uint256) unDelegatedAmountPerCollateral;
}
}

Expand Down Expand Up @@ -220,6 +221,7 @@ library DelegationIntent {
int256 deltaCollateralAmountD18;
uint256 leverage;
uint32 declarationTime;
uint128 epochId;
}
function load(uint256 id) internal pure returns (Data storage delegationIntent) {
bytes32 s = keccak256(abi.encode("io.synthetix.synthetix.DelegationIntent", id));
Expand Down
4 changes: 3 additions & 1 deletion markets/perps-market/storage.dump.sol
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,8 @@ library AccountDelegationIntents {
SetUtil.UintSet intentsId;
mapping(bytes32 => SetUtil.UintSet) intentsByPair;
SetUtil.AddressSet delegatedCollaterals;
mapping(address => int256) netDelegatedAmountPerCollateral;
mapping(address => uint256) delegatedAmountPerCollateral;
mapping(address => uint256) unDelegatedAmountPerCollateral;
}
}

Expand Down Expand Up @@ -219,6 +220,7 @@ library DelegationIntent {
int256 deltaCollateralAmountD18;
uint256 leverage;
uint32 declarationTime;
uint128 epochId;
}
function load(uint256 id) internal pure returns (Data storage delegationIntent) {
bytes32 s = keccak256(abi.encode("io.synthetix.synthetix.DelegationIntent", id));
Expand Down
1 change: 1 addition & 0 deletions protocol/synthetix/cannonfile.test.toml
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ contracts = [
"RewardsManagerModule",
"UtilsModule",
"VaultModule",
"VaultIntentViewsModule",
"TestableAccountStorage",
"TestableAccountRBACStorage",
"TestableCollateralStorage",
Expand Down
4 changes: 4 additions & 0 deletions protocol/synthetix/cannonfile.toml
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,9 @@ artifact = "contracts/modules/core/UtilsModule.sol:UtilsModule"
[contract.VaultModule]
artifact = "contracts/modules/core/VaultModule.sol:VaultModule"

[contract.VaultIntentViewsModule]
artifact = "contracts/modules/core/VaultIntentViewsModule.sol:VaultIntentViewsModule"

[contract.AccountTokenModule]
artifact = "contracts/modules/account/AccountTokenModule.sol:AccountTokenModule"

Expand Down Expand Up @@ -118,6 +121,7 @@ contracts = [
"RewardsManagerModule",
"UtilsModule",
"VaultModule",
"VaultIntentViewsModule",
]

[contract.InitialCoreProxy]
Expand Down
11 changes: 10 additions & 1 deletion protocol/synthetix/contracts/interfaces/ICollateralModule.sol
Original file line number Diff line number Diff line change
Expand Up @@ -102,11 +102,20 @@ interface ICollateralModule {
* @return totalDeposited The total collateral deposited in the account, denominated with 18 decimals of precision.
* @return totalAssigned The amount of collateral in the account that is delegated to pools, denominated with 18 decimals of precision.
* @return totalLocked The amount of collateral in the account that cannot currently be undelegated from a pool, denominated with 18 decimals of precision.
* @return totalPendingToDelegate The amount of collateral in the account that cannot currently be undelegated from a pool because is intended to be delegated, denominated with 18 decimals of precision.
*/
function getAccountCollateral(
uint128 accountId,
address collateralType
) external view returns (uint256 totalDeposited, uint256 totalAssigned, uint256 totalLocked);
)
external
view
returns (
uint256 totalDeposited,
uint256 totalAssigned,
uint256 totalLocked,
uint256 totalPendingToDelegate
);

/**
* @notice Returns the amount of collateral of type `collateralType` deposited with account `accountId` that can be withdrawn or delegated to pools.
Expand Down
109 changes: 109 additions & 0 deletions protocol/synthetix/contracts/interfaces/IVaultIntentViewsModule.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
//SPDX-License-Identifier: MIT
pragma solidity >=0.8.11 <0.9.0;

/**
* @title Views for Delegation Intents for Vault.
*/
interface IVaultIntentViewsModule {
/**
* @notice Returns details of the requested intent.
* @param accountId The id of the account owning the intent.
* @param intentId The id of the intents.
* @return poolId The id of the pool associated with the position.
* @return collateralType The address of the collateral used in the position.
* @return deltaCollateralAmountD18 The delta amount of collateral delegated in the position, denominated with 18 decimals of precision.
* @return leverage The new leverage amount used in the position, denominated with 18 decimals of precision.
* @return declarationTime The time at which the intent was declared.
* @return processingStartTime The time at which the intent execution window starts.
* @return processingEndTime The time at which the intent execution window ends.
*/
function getAccountIntent(
uint128 accountId,
uint256 intentId
)
external
view
returns (
uint128 poolId,
address collateralType,
int256 deltaCollateralAmountD18,
uint256 leverage,
uint32 declarationTime,
uint32 processingStartTime,
uint32 processingEndTime
);

/**
* @notice Returns the total amount of collateral intended to be delegated to the vault by the account.
* @param accountId The id of the account owning the intents.
* @param collateralType The address of the collateral.
* @return delegatedPerCollateral The total amount of collateral intended to be delegated to the vault by the account, denominated with 18 decimals of precision.
*/
function getIntentDelegatedPerCollateral(
uint128 accountId,
address collateralType
) external view returns (uint256 delegatedPerCollateral);

/**
* @notice Returns the total amount of collateral intended to be undelegated to the vault by the account.
* @param accountId The id of the account owning the intents.
* @param collateralType The address of the collateral.
* @return undelegatedPerCollateral The total amount of collateral intended to be undelegated to the vault by the account, denominated with 18 decimals of precision.
*/
function getIntentUndelegatedPerCollateral(
uint128 accountId,
address collateralType
) external view returns (uint256 undelegatedPerCollateral);

/**
* @notice Returns the total executable (not expired) amount of collateral intended to be delegated to the vault by the account.
* @param accountId The id of the account owning the intents.
* @param poolId The id of the pool associated with the position.
* @param collateralType The address of the collateral.
* @return accumulatedIntentDelta The total amount of collateral intended to be delegated that is not expired, denominated with 18 decimals of precision.
*/
function getExecutableDelegationAccumulated(
uint128 accountId,
uint128 poolId,
address collateralType
) external view returns (int256 accumulatedIntentDelta);

/**
* @notice Returns the list of executable (by timing) intents for the account.
* @param accountId The id of the account owning the intents.
* @param maxProcessableIntent The maximum number of intents to process.
* @return intentIds The list of intents.
* @return foundIntents The number of found intents.
*
* @dev The array of intent ids might have empty items at the end, use `foundIntents` to know the actual number
* of valid intents.
*/
function getAccountExecutableIntentIds(
uint128 accountId,
uint256 maxProcessableIntent
) external view returns (uint256[] memory intentIds, uint256 foundIntents);

/**
* @notice Returns the list of expired (by timing) intents for the account.
* @param accountId The id of the account owning the intents.
* @param maxProcessableIntent The maximum number of intents to process.
* @return intentIds The list of intents.
* @return foundIntents The number of found intents.
*
* @dev The array of intent ids might have empty items at the end, use `foundIntents` to know the actual number
* of valid intents.
*/
function getAccountExpiredIntentIds(
uint128 accountId,
uint256 maxProcessableIntent
) external view returns (uint256[] memory intentIds, uint256 foundIntents);

/**
* @notice Returns the list of intents for the account.
* @param accountId The id of the account owning the intents.
* @return intentIds The list of intents.
*/
function getAccountIntentIds(
uint128 accountId
) external view returns (uint256[] memory intentIds);
}
93 changes: 1 addition & 92 deletions protocol/synthetix/contracts/interfaces/IVaultModule.sol
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ interface IVaultModule {
*/
error ExceedingUndelegateAmount(
int256 deltaCollateralAmountD18,
int256 cachedDeltaCollateralAmountD18,
uint256 cachedDeltaCollateralAmountD18,
int256 totalDeltaCollateralAmountD18,
uint256 currentCollateralAmount
);
Expand Down Expand Up @@ -263,58 +263,6 @@ interface IVaultModule {
*/
function forceDeleteAllAccountIntents(uint128 accountId) external;

/**
* @notice Returns details of the requested intent.
* @param accountId The id of the account owning the intent.
* @param intentId The id of the intents.
* @return poolId The id of the pool associated with the position.
* @return collateralType The address of the collateral used in the position.
* @return deltaCollateralAmountD18 The delta amount of collateral delegated in the position, denominated with 18 decimals of precision.
* @return leverage The new leverage amount used in the position, denominated with 18 decimals of precision.
* @return declarationTime The time at which the intent was declared.
* @return processingStartTime The time at which the intent execution window starts.
* @return processingEndTime The time at which the intent execution window ends.
*/
function getAccountIntent(
uint128 accountId,
uint256 intentId
)
external
view
returns (
uint128 poolId,
address collateralType,
int256 deltaCollateralAmountD18,
uint256 leverage,
uint32 declarationTime,
uint32 processingStartTime,
uint32 processingEndTime
);

/**
* @notice Returns the total (positive and negative) amount of collateral intended to be delegated to the vault by the account.
* @param accountId The id of the account owning the intents.
* @param collateralType The address of the collateral.
* @return netDelegatedPerCollateral The total amount of collateral intended to be delegated to the vault by the account, denominated with 18 decimals of precision.
*/
function getNetDelegatedPerCollateral(
uint128 accountId,
address collateralType
) external view returns (int256 netDelegatedPerCollateral);

/**
* @notice Returns the total executable (not expired) amount of collateral intended to be delegated to the vault by the account.
* @param accountId The id of the account owning the intents.
* @param poolId The id of the pool associated with the position.
* @param collateralType The address of the collateral.
* @return accumulatedIntentDelta The total amount of collateral intended to be delegated that is not expired, denominated with 18 decimals of precision.
*/
function getExecutableDelegationAccumulated(
uint128 accountId,
uint128 poolId,
address collateralType
) external view returns (int256 accumulatedIntentDelta);

/**
* @notice Returns the amount of debt that needs to be repaid, which allows execution of intents that aim at undelegating collalteral, ensuring complyiance with the issuance ratio requirements
* @param accountId The id of the account owning the position.
Expand All @@ -333,45 +281,6 @@ interface IVaultModule {
uint256 collateralPrice
) external view returns (uint256 howMuchToRepayD18);

/**
* @notice Returns the list of executable (by timing) intents for the account.
* @param accountId The id of the account owning the intents.
* @param maxProcessableIntent The maximum number of intents to process.
* @return intentIds The list of intents.
* @return foundIntents The number of found intents.
*
* @dev The array of intent ids might have empty items at the end, use `foundIntents` to know the actual number
* of valid intents.
*/
function getAccountExecutableIntentIds(
uint128 accountId,
uint256 maxProcessableIntent
) external view returns (uint256[] memory intentIds, uint256 foundIntents);

/**
* @notice Returns the list of expired (by timing) intents for the account.
* @param accountId The id of the account owning the intents.
* @param maxProcessableIntent The maximum number of intents to process.
* @return intentIds The list of intents.
* @return foundIntents The number of found intents.
*
* @dev The array of intent ids might have empty items at the end, use `foundIntents` to know the actual number
* of valid intents.
*/
function getAccountExpiredIntentIds(
uint128 accountId,
uint256 maxProcessableIntent
) external view returns (uint256[] memory intentIds, uint256 foundIntents);

/**
* @notice Returns the list of intents for the account.
* @param accountId The id of the account owning the intents.
* @return intentIds The list of intents.
*/
function getAccountIntentIds(
uint128 accountId
) external view returns (uint256[] memory intentIds);

/**
* @notice Returns the collateralization ratio of the specified liquidity position. If debt is negative, this function will return 0.
* @dev Call this function using `callStatic` to treat it as a view function.
Expand Down
3 changes: 3 additions & 0 deletions protocol/synthetix/contracts/modules/core/AccountModule.sol
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,9 @@ contract AccountModule is IAccountModule {
account.rbac.revokeAllPermissions(permissionedAddresses[i]);
}

// clean all pending intents
account.cleanAllIntents();

account.rbac.setOwner(to);
}

Expand Down
19 changes: 14 additions & 5 deletions protocol/synthetix/contracts/modules/core/CollateralModule.sol
Original file line number Diff line number Diff line change
Expand Up @@ -82,14 +82,18 @@ contract CollateralModule is ICollateralModule {
.load(collateralType)
.convertTokenToSystemAmount(tokenAmount);

(uint256 totalDeposited, uint256 totalAssigned, uint256 totalLocked) = account
.getCollateralTotals(collateralType);
(
uint256 totalDeposited,
uint256 totalAssigned,
uint256 totalLocked,
uint256 pendingToDelegate
) = account.getCollateralTotals(collateralType);

// The amount that cannot be withdrawn from the protocol is the max of either
// locked collateral or delegated collateral.
uint256 unavailableCollateral = totalLocked > totalAssigned ? totalLocked : totalAssigned;

uint256 availableForWithdrawal = totalDeposited - unavailableCollateral;
uint256 availableForWithdrawal = totalDeposited - unavailableCollateral - pendingToDelegate;
if (tokenAmountD18 > availableForWithdrawal) {
revert InsufficientAccountCollateral(tokenAmountD18);
}
Expand All @@ -111,7 +115,12 @@ contract CollateralModule is ICollateralModule {
external
view
override
returns (uint256 totalDeposited, uint256 totalAssigned, uint256 totalLocked)
returns (
uint256 totalDeposited,
uint256 totalAssigned,
uint256 totalLocked,
uint256 totalPendingToDelegate
)
{
return Account.load(accountId).getCollateralTotals(collateralType);
}
Expand Down Expand Up @@ -212,7 +221,7 @@ contract CollateralModule is ICollateralModule {
AccountRBAC._ADMIN_PERMISSION
);

(uint256 totalDeposited, , uint256 totalLocked) = account.getCollateralTotals(
(uint256 totalDeposited, , uint256 totalLocked, ) = account.getCollateralTotals(
collateralType
);

Expand Down
Loading