Skip to content

Commit

Permalink
TOB-AJNA-2: global scalar (at index 8192) is never updated (#753)
Browse files Browse the repository at this point in the history
* TOB-AJNA-2: global scalar (at index 8192) is never updated
- save an SLOAD in Deposits.treeSum as scalar is not updated (always 1)

* Changes after review: add F5 invariant
  • Loading branch information
grandizzy authored Apr 20, 2023
1 parent b97455f commit 45d8448
Show file tree
Hide file tree
Showing 5 changed files with 23 additions and 4 deletions.
5 changes: 5 additions & 0 deletions src/base/Pool.sol
Original file line number Diff line number Diff line change
Expand Up @@ -780,6 +780,11 @@ abstract contract Pool is Clone, ReentrancyGuard, Multicall, IPool {
return PoolCommons.utilization(emaState);
}

/// @inheritdoc IPoolDerivedState
function depositScale(uint256 index_) external view override returns (uint256) {
return deposits.scaling[index_];
}

/// @inheritdoc IPoolState
function emasInfo() external view override returns (uint256, uint256, uint256, uint256) {
return (
Expand Down
9 changes: 9 additions & 0 deletions src/interfaces/pool/commons/IPoolDerivedState.sol
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,13 @@ interface IPoolDerivedState {
*/
function depositUtilization() external view returns (uint256);

/**
* @notice Returns the scaling value of deposit at given index.
* @param index_ Deposit index.
* @return Deposit scaling.
*/
function depositScale(
uint256 index_
) external view returns (uint256);

}
6 changes: 2 additions & 4 deletions src/libraries/internal/Deposits.sol
Original file line number Diff line number Diff line change
Expand Up @@ -321,10 +321,8 @@ library Deposits {
function treeSum(
DepositsState storage deposits_
) internal view returns (uint256) {
// In a scaled Fenwick tree, sum is at the root node, but needs to be scaled
uint256 scaling = deposits_.scaling[SIZE];
// scaling == 0 means scale factor is actually 1
return (scaling != 0) ? Maths.wmul(scaling, deposits_.values[SIZE]) : deposits_.values[SIZE];
// In a scaled Fenwick tree, sum is at the root node and never scaled
return deposits_.values[SIZE];
}

/**
Expand Down
1 change: 1 addition & 0 deletions tests/INVARIANTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
- **F2**: For any index `i`, the prefix sum up to and including `i` is the sum of values stored in indices `j<=i`
- **F3**: For any index `i < MAX_FENWICK_INDEX`, `findIndexOfSum(prefixSum(i)) > i`
- **F4**: For any index i, there is zero deposit above i and below findIndexOfSum(prefixSum(i) + 1): `depositAtIndex(j) == 0 for i < j < findIndexOfSum(prefixSum(i)+1)`
- **F5**: Global scalar is never updated (`DepositsState.scaling[8192]` is always 0)

## Exchange rate invariants ##
- **R1**: Exchange rates are unchanged by pledging collateral
Expand Down
6 changes: 6 additions & 0 deletions tests/forge/invariants/base/BasicInvariants.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ abstract contract BasicInvariants is BaseInvariants {
* F2: For any index i, the prefix sum up to and including i is the sum of values stored in indices j<=i
* F3: For any index i < MAX_FENWICK_INDEX, findIndexOfSum(prefixSum(i)) > i
* F4: For any index i, there is zero deposit above i and below findIndexOfSum(prefixSum(i) + 1): findIndexOfSum(prefixSum(i)) == findIndexOfSum(prefixSum(j) - deposits.valueAt(j)), where j is the next index from i with deposits != 0
* F5: Global scalar is never updated (`DepositsState.values[8192]` is always 0)
****************************************************************************************************************************************/

// checks pool lps are equal to sum of all lender lps in a bucket
Expand Down Expand Up @@ -352,6 +353,11 @@ abstract contract BasicInvariants is BaseInvariants {
}
}

// **F5**: Global scalar is never updated (`DepositsState.scaling[8192]` is always 0)
function invariant_fenwick_globalscalar_F5() public useCurrentTimestamp {
require(_pool.depositScale(8192) == 0, "F5: Global scalar was updated");
}

function invariant_call_summary() public virtual useCurrentTimestamp {
console.log("\nCall Summary\n");
console.log("--Lender----------");
Expand Down

0 comments on commit 45d8448

Please sign in to comment.