diff --git a/contracts/src/Interfaces/IStabilityPool.sol b/contracts/src/Interfaces/IStabilityPool.sol index e9cdb115..96c6f413 100644 --- a/contracts/src/Interfaces/IStabilityPool.sol +++ b/contracts/src/Interfaces/IStabilityPool.sol @@ -45,54 +45,32 @@ interface IStabilityPool is ILiquityBase { address _sortedTrovesAddress, address _priceFeedAddress ) external; + + /* provideToSP(): + * - Calculates depositor's ETH gain + * - Calculates the compounded deposit + * - Increases deposit, and takes new snapshots of accumulators P and S + * - Sends depositor's accumulated ETH gains to depositor + */ + function provideToSP(uint _amount) external; - /* - * Initial checks: - * - Frontend is registered or zero address - * - Sender is not a registered frontend - * - _amount is not zero - * --- - * - Tags the deposit with the provided front end tag param, if it's a new deposit - * - Sends depositor's accumulated ETH gains to depositor - * - Increases deposit and tagged front end's stake, and takes new snapshots for each. - */ - function provideToSP(uint _amount, address _frontEndTag) external; - - /* - * Initial checks: - * - _amount is zero or there are no under collateralized troves left in the system - * - User has a non zero deposit - * --- - * - Removes the deposit's front end tag if it is a full withdrawal - * - Sends all depositor's accumulated ETH gains to depositor - * - Decreases deposit and tagged front end's stake, and takes new snapshots for each. - * - * If _amount > userDeposit, the user withdraws all of their compounded deposit. - */ + + /* withdrawFromSP(): + * - Calculates depositor's ETH gain + * - Calculates the compounded deposit + * - Sends the requested BOLD withdrawal to depositor + * - (If _amount > userDeposit, the user withdraws all of their compounded deposit) + * - Decreases deposit by withdrawn amount and takes new snapshots of accumulators P and S + */ function withdrawFromSP(uint _amount) external; - /* - * Initial checks: - * - User has a non zero deposit - * - User has an open trove - * - User has some ETH gain - * --- - * - Transfers the depositor's entire ETH gain from the Stability Pool to the caller's trove - * - Leaves their compounded deposit in the Stability Pool - * - Updates snapshots for deposit and tagged front end stake - */ + /* withdrawETHGainToTrove(): + * - Transfers the depositor's entire ETH gain from the Stability Pool to the caller's trove + * - Leaves their compounded deposit in the Stability Pool + * - Takes new snapshots of accumulators P and S + */ function withdrawETHGainToTrove(address _upperHint, address _lowerHint) external; - /* - * Initial checks: - * - Frontend (sender) not already registered - * - User (sender) has no deposit - * - _kickbackRate is in the range [0, 100%] - * --- - * Front end makes a one-time selection of kickback rate upon registering - */ - function registerFrontEnd(uint _kickbackRate) external; - /* * Initial checks: * - Caller is TroveManager @@ -124,13 +102,6 @@ interface IStabilityPool is ILiquityBase { */ function getCompoundedBoldDeposit(address _depositor) external view returns (uint); - /* - * Return the front end's compounded stake. - * - * The front end's compounded stake is equal to the sum of its depositors' compounded deposits. - */ - function getCompoundedFrontEndStake(address _frontEnd) external view returns (uint); - /* * Fallback function * Only callable by Active Pool, it just accounts for ETH received diff --git a/contracts/src/StabilityPool.sol b/contracts/src/StabilityPool.sol index 777ab57e..550ff4e5 100644 --- a/contracts/src/StabilityPool.sol +++ b/contracts/src/StabilityPool.sol @@ -145,14 +145,8 @@ contract StabilityPool is LiquityBase, Ownable, CheckContract, IStabilityPool { // --- Data structures --- - struct FrontEnd { - uint kickbackRate; - bool registered; - } - struct Deposit { uint initialValue; - address frontEndTag; } struct Snapshots { @@ -166,10 +160,6 @@ contract StabilityPool is LiquityBase, Ownable, CheckContract, IStabilityPool { mapping (address => Deposit) public deposits; // depositor address -> Deposit struct mapping (address => Snapshots) public depositSnapshots; // depositor address -> snapshots struct - mapping (address => FrontEnd) public frontEnds; // front end address -> FrontEnd struct - mapping (address => uint) public frontEndStakes; // front end address -> last recorded total deposits, tagged with that front end - mapping (address => Snapshots) public frontEndSnapshots; // front end address -> snapshots struct - /* Product 'P': Running product by which to multiply an initial deposit, in order to find the current compounded deposit, * after a series of liquidations have occurred, each of which cancel some Bold debt with the deposit. * @@ -219,13 +209,8 @@ contract StabilityPool is LiquityBase, Ownable, CheckContract, IStabilityPool { event EpochUpdated(uint128 _currentEpoch); event ScaleUpdated(uint128 _currentScale); - event FrontEndRegistered(address indexed _frontEnd, uint _kickbackRate); - event FrontEndTagSet(address indexed _depositor, address indexed _frontEnd); - event DepositSnapshotUpdated(address indexed _depositor, uint _P, uint _S); - event FrontEndSnapshotUpdated(address indexed _frontEnd, uint _P); event UserDepositChanged(address indexed _depositor, uint _newDeposit); - event FrontEndStakeChanged(address indexed _frontEnd, uint _newFrontEndStake, address _depositor); event ETHGainWithdrawn(address indexed _depositor, uint _ETH, uint _boldLoss); event EtherSent(address _to, uint _amount); @@ -281,31 +266,20 @@ contract StabilityPool is LiquityBase, Ownable, CheckContract, IStabilityPool { // --- External Depositor Functions --- /* provideToSP(): - * - * - Tags the deposit with the provided front end tag param, if it's a new deposit - * - Sends depositor's accumulated ETH to depositor - * - Increases deposit and tagged front end's stake, and takes new snapshots for each. + * - Calculates depositor's ETH gain + * - Calculates the compounded deposit + * - Increases deposit, and takes new snapshots of accumulators P and S + * - Sends depositor's accumulated ETH gains to depositor */ - function provideToSP(uint _amount, address _frontEndTag) external override { - _requireFrontEndIsRegisteredOrZero(_frontEndTag); - _requireFrontEndNotRegistered(msg.sender); + function provideToSP(uint _amount) external override { _requireNonZeroAmount(_amount); uint initialDeposit = deposits[msg.sender].initialValue; - if (initialDeposit == 0) {_setFrontEndTag(msg.sender, _frontEndTag);} uint depositorETHGain = getDepositorETHGain(msg.sender); uint compoundedBoldDeposit = getCompoundedBoldDeposit(msg.sender); uint boldLoss = initialDeposit - compoundedBoldDeposit; // Needed only for event log - address frontEnd = deposits[msg.sender].frontEndTag; - - // Update front end stake - uint compoundedFrontEndStake = getCompoundedFrontEndStake(frontEnd); - uint newFrontEndStake = compoundedFrontEndStake + _amount; - _updateFrontEndStakeAndSnapshots(frontEnd, newFrontEndStake); - emit FrontEndStakeChanged(frontEnd, newFrontEndStake, msg.sender); - _sendBoldtoStabilityPool(msg.sender, _amount); uint newDeposit = compoundedBoldDeposit + _amount; @@ -318,11 +292,11 @@ contract StabilityPool is LiquityBase, Ownable, CheckContract, IStabilityPool { } /* withdrawFromSP(): - * - * - Removes the deposit's front end tag if it is a full withdrawal - * - Decreases deposit and tagged front end's stake, and takes new snapshots for each. - * - * If _amount > userDeposit, the user withdraws all of their compounded deposit. + * - Calculates depositor's ETH gain + * - Calculates the compounded deposit + * - Sends the requested BOLD withdrawal to depositor + * - (If _amount > userDeposit, the user withdraws all of their compounded deposit) + * - Decreases deposit by withdrawn amount and takes new snapshots of accumulators P and S */ function withdrawFromSP(uint _amount) external override { if (_amount !=0) {_requireNoUnderCollateralizedTroves();} @@ -335,14 +309,6 @@ contract StabilityPool is LiquityBase, Ownable, CheckContract, IStabilityPool { uint BoldtoWithdraw = LiquityMath._min(_amount, compoundedBoldDeposit); uint boldLoss = initialDeposit - compoundedBoldDeposit; // Needed only for event log - address frontEnd = deposits[msg.sender].frontEndTag; - - // Update front end stake - uint compoundedFrontEndStake = getCompoundedFrontEndStake(frontEnd); - uint newFrontEndStake = compoundedFrontEndStake - BoldtoWithdraw; - _updateFrontEndStakeAndSnapshots(frontEnd, newFrontEndStake); - emit FrontEndStakeChanged(frontEnd, newFrontEndStake, msg.sender); - _sendBoldToDepositor(msg.sender, BoldtoWithdraw); // Update deposit @@ -355,10 +321,11 @@ contract StabilityPool is LiquityBase, Ownable, CheckContract, IStabilityPool { _sendETHGainToDepositor(depositorETHGain); } - /* withdrawETHGainToTrove: + /* withdrawETHGainToTrove(): * - Transfers the depositor's entire ETH gain from the Stability Pool to the caller's trove * - Leaves their compounded deposit in the Stability Pool - * - Updates snapshots for deposit and tagged front end stake */ + * - Takes new snapshots of accumulators P and S + */ function withdrawETHGainToTrove(address _upperHint, address _lowerHint) external override { uint initialDeposit = deposits[msg.sender].initialValue; _requireUserHasDeposit(initialDeposit); @@ -370,14 +337,6 @@ contract StabilityPool is LiquityBase, Ownable, CheckContract, IStabilityPool { uint compoundedBoldDeposit = getCompoundedBoldDeposit(msg.sender); uint boldLoss = initialDeposit - compoundedBoldDeposit; // Needed only for event log - address frontEnd = deposits[msg.sender].frontEndTag; - - // Update front end stake - uint compoundedFrontEndStake = getCompoundedFrontEndStake(frontEnd); - uint newFrontEndStake = compoundedFrontEndStake; - _updateFrontEndStakeAndSnapshots(frontEnd, newFrontEndStake); - emit FrontEndStakeChanged(frontEnd, newFrontEndStake, msg.sender); - _updateDepositAndSnapshots(msg.sender, compoundedBoldDeposit); /* Emit events before transferring ETH gain to Trove. @@ -526,7 +485,7 @@ contract StabilityPool is LiquityBase, Ownable, CheckContract, IStabilityPool { emit StabilityPoolBoldBalanceUpdated(newTotalBoldDeposits); } - // --- Reward calculator functions for depositor and front end --- + // --- Reward calculator functions for depositor --- /* Calculates the ETH gain earned by the deposit since its last snapshots were taken. * Given by the formula: E = d0 * (S - S(0))/P(0) @@ -563,7 +522,7 @@ contract StabilityPool is LiquityBase, Ownable, CheckContract, IStabilityPool { return ETHGain; } - // --- Compounded deposit and compounded front end stake --- + // --- Compounded deposit --- /* * Return the user's compounded deposit. Given by the formula: d = d0 * P/P(0) @@ -579,23 +538,6 @@ contract StabilityPool is LiquityBase, Ownable, CheckContract, IStabilityPool { return compoundedDeposit; } - /* - * Return the front end's compounded stake. Given by the formula: D = D0 * P/P(0) - * where P(0) is the depositor's snapshot of the product P, taken at the last time - * when one of the front end's tagged deposits updated their deposit. - * - * The front end's compounded stake is equal to the sum of its depositors' compounded deposits. - */ - function getCompoundedFrontEndStake(address _frontEnd) public view override returns (uint) { - uint frontEndStake = frontEndStakes[_frontEnd]; - if (frontEndStake == 0) { return 0; } - - Snapshots memory snapshots = frontEndSnapshots[_frontEnd]; - - uint compoundedFrontEndStake = _getCompoundedStakeFromSnapshots(frontEndStake, snapshots); - return compoundedFrontEndStake; - } - // Internal function, used to calculcate compounded deposits and compounded front end stakes. function _getCompoundedStakeFromSnapshots( uint initialStake, @@ -670,33 +612,12 @@ contract StabilityPool is LiquityBase, Ownable, CheckContract, IStabilityPool { _decreaseBold(BoldWithdrawal); } - // --- External Front End functions --- - - // Front end makes a one-time selection of kickback rate upon registering - function registerFrontEnd(uint _kickbackRate) external override { - _requireFrontEndNotRegistered(msg.sender); - _requireUserHasNoDeposit(msg.sender); - _requireValidKickbackRate(_kickbackRate); - - frontEnds[msg.sender].kickbackRate = _kickbackRate; - frontEnds[msg.sender].registered = true; - - emit FrontEndRegistered(msg.sender, _kickbackRate); - } - // --- Stability Pool Deposit Functionality --- - function _setFrontEndTag(address _depositor, address _frontEndTag) internal { - deposits[_depositor].frontEndTag = _frontEndTag; - emit FrontEndTagSet(_depositor, _frontEndTag); - } - - function _updateDepositAndSnapshots(address _depositor, uint _newValue) internal { deposits[_depositor].initialValue = _newValue; if (_newValue == 0) { - delete deposits[_depositor].frontEndTag; delete depositSnapshots[_depositor]; emit DepositSnapshotUpdated(_depositor, 0, 0); return; @@ -717,27 +638,6 @@ contract StabilityPool is LiquityBase, Ownable, CheckContract, IStabilityPool { emit DepositSnapshotUpdated(_depositor, currentP, currentS); } - function _updateFrontEndStakeAndSnapshots(address _frontEnd, uint _newValue) internal { - frontEndStakes[_frontEnd] = _newValue; - - if (_newValue == 0) { - delete frontEndSnapshots[_frontEnd]; - emit FrontEndSnapshotUpdated(_frontEnd, 0); - return; - } - - uint128 currentScaleCached = currentScale; - uint128 currentEpochCached = currentEpoch; - uint currentP = P; - - // Record new snapshots of the latest running product P - frontEndSnapshots[_frontEnd].P = currentP; - frontEndSnapshots[_frontEnd].scale = currentScaleCached; - frontEndSnapshots[_frontEnd].epoch = currentEpochCached; - - emit FrontEndSnapshotUpdated(_frontEnd, currentP); - } - // --- 'require' functions --- function _requireCallerIsActivePool() internal view { @@ -777,15 +677,6 @@ contract StabilityPool is LiquityBase, Ownable, CheckContract, IStabilityPool { require(ETHGain > 0, "StabilityPool: caller must have non-zero ETH Gain"); } - function _requireFrontEndNotRegistered(address _address) internal view { - require(!frontEnds[_address].registered, "StabilityPool: must not already be a registered front end"); - } - - function _requireFrontEndIsRegisteredOrZero(address _address) internal view { - require(frontEnds[_address].registered || _address == address(0), - "StabilityPool: Tag must be a registered front end, or the zero address"); - } - function _requireValidKickbackRate(uint _kickbackRate) internal pure { require (_kickbackRate <= DECIMAL_PRECISION, "StabilityPool: Kickback rate must be in range [0,1]"); } diff --git a/contracts/src/test/basicOps.t.sol b/contracts/src/test/basicOps.t.sol index f8625469..0fc8b51c 100644 --- a/contracts/src/test/basicOps.t.sol +++ b/contracts/src/test/basicOps.t.sol @@ -37,8 +37,6 @@ contract BasicOps is DevTestSetup { assertEq(trovesCount, 1); } - // adjustTrove - function testAdjustTrove() public { priceFeed.setPrice(2000e18); vm.startPrank(A); @@ -115,10 +113,7 @@ contract BasicOps is DevTestSetup { uint256 price = priceFeed.fetchPrice(); // Check CR_A < MCR and TCR > CCR - console.log(troveManager.getCurrentICR(A, price), "A ICR"); assertLt(troveManager.getCurrentICR(A, price), MCR); - - console.log(troveManager.getTCR(price) , "TCR"); assertGt(troveManager.getTCR(price), CCR); uint256 trovesCount = troveManager.getTroveOwnersCount(); @@ -131,34 +126,32 @@ contract BasicOps is DevTestSetup { assertEq(trovesCount, 1); } - // SP deposit function testSPDeposit() public { priceFeed.setPrice(2000e18); vm.startPrank(A); borrowerOperations.openTrove{value: 2 ether}(1e18, 2000e18, ZERO_ADDRESS, ZERO_ADDRESS); // A makes an SP deposit - stabilityPool.provideToSP(100e18, ZERO_ADDRESS); + stabilityPool.provideToSP(100e18); // time passes vm.warp(block.timestamp + 7 days); // A tops up their SP deposit - stabilityPool.provideToSP(100e18, ZERO_ADDRESS); + stabilityPool.provideToSP(100e18); // Check A's balance decreased and SP deposit increased assertEq(boldToken.balanceOf(A), 1800e18); assertEq(stabilityPool.getCompoundedBoldDeposit(A), 200e18); } - // SP withdraw function testSPWithdrawal() public { priceFeed.setPrice(2000e18); vm.startPrank(A); borrowerOperations.openTrove{value: 2 ether}(1e18, 2000e18, ZERO_ADDRESS, ZERO_ADDRESS); // A makes an SP deposit - stabilityPool.provideToSP(100e18, ZERO_ADDRESS); + stabilityPool.provideToSP(100e18); // time passes vm.warp(block.timestamp + 7 days);