ebtc-protocol / ebtc

GNU General Public License v3.0
56 stars 25 forks source link

Feat/snapshot removal research #732

Closed dapp-whisperer closed 9 months ago

CodingNameKiki commented 12 months ago

l think we have similar results here as the previous design of the system, the spec difference is that we no longer use totalStakesSnapshot and totalCollateralSnapshot to calculate the stake instead we use the latest totalStakes and totalCollateralShares. The outcome should be the same and still have staled debt redistribution duo to not synced Cdps.

l am curious about the results when removing both the stakes and snapshot functionality? Won't we be more accurate if we calculate everything needed based on the system coll shares:

    function calcFeeUponStakingReward(
        uint256 _newIndex,
        uint256 _prevIndex
    ) public view returns (uint256, uint256, uint256) {
        require(_newIndex > _prevIndex, "CDPManager: only take fee with bigger new index");
        uint256 deltaIndex = _newIndex - _prevIndex;
        uint256 deltaIndexFees = (deltaIndex * stakingRewardSplit) / MAX_REWARD_SPLIT;

        // we take the fee for all CDPs immediately which is scaled by index precision
+       uint256 _cachedAllColl = getSystemCollShares();
+       uint256 _deltaFeeSplit = deltaIndexFees * _cachedAllColl;
        // return the values to update the global fee accumulator
        uint256 _feeTaken = collateral.getSharesByPooledEth(_deltaFeeSplit) / DECIMAL_PRECISION;
        uint256 _deltaFeeSplitShare = (_feeTaken * DECIMAL_PRECISION) +
            systemStEthFeePerUnitIndexError;
+       uint256 _deltaFeePerUnit = _deltaFeeSplitShare / _cachedAllColl;
+       uint256 _perUnitError = _deltaFeeSplitShare - (_deltaFeePerUnit * _cachedAllColl);
        return (_feeTaken, _deltaFeePerUnit, _perUnitError);
    }
    function _redistributeDebt(uint256 _debt) internal {
        if (_debt == 0) {
            return;
        }

        uint256 EBTCDebtNumerator = (_debt * DECIMAL_PRECISION) + lastEBTCDebtErrorRedistribution;

        // Get the per-unit-staked terms
+       uint256 _cachedAllColl = getSystemCollShares();
+       uint256 EBTCDebtRewardPerUnitStaked = EBTCDebtNumerator / _cachedAllColl;

        lastEBTCDebtErrorRedistribution =
            EBTCDebtNumerator -
+           (EBTCDebtRewardPerUnitStaked * _cachedAllColl);

        // Add per-unit-staked terms to the running totals
        systemDebtRedistributionIndex = systemDebtRedistributionIndex + EBTCDebtRewardPerUnitStaked;

        emit SystemDebtRedistributionIndexUpdated(systemDebtRedistributionIndex);
    }
CodingNameKiki commented 11 months ago

Posting this as a reminder.

https://gist.github.com/CodingNameKiki/a3b887756e686de8361952536a931c8b

The difference between using the snapshots and the live stake is:

Logs:
  ---------------------------- First Cdp
  Snapshot Stake   :   1999999999999999988
  Live Stake       :   2000000000000000009
  ---------------------------- Second Cdp
  Snapshot Stake   :   3999999999999999977
  Live Stake       :   4000000000000000017
  ---------------------------- Third Cdp
  Snapshot Stake   :   7999999999999999955
  Live Stake       :   8000000000000000034
CodingNameKiki commented 11 months ago
  • Test begins with some initial CDPs and a series of split fee claim and liquidation events
  • Now create a target CDP1
  • Then create another CDP2 with collateral equal to current system total collaterals
  • Lastly create another target CDP3 with same collateral as CDP1
  • Check the stakes of CDP1 & CDP3 using snapshot vs spot values

https://gist.github.com/CodingNameKiki/289ab331e71dc6d0520129f95a6547cf

Difference between the Cdp stake by using both the snapshot and the live stake ratio in the above example:

Logs:
  ---------------------------- First Cdp
  Snapshot Stake   :   1999802759179916502
  Live Stake       :   2000000000000000000
  ---------------------------- Third Cdp
  Snapshot Stake   :   1999802759179916502
  Live Stake       :   2000000000000000000