Skip to content

Commit

Permalink
fixed the math
Browse files Browse the repository at this point in the history
  • Loading branch information
daopunk committed May 22, 2024
1 parent a68b210 commit b5e337d
Show file tree
Hide file tree
Showing 2 changed files with 104 additions and 29 deletions.
34 changes: 17 additions & 17 deletions src/contracts/ODSaviour.sol
Original file line number Diff line number Diff line change
Expand Up @@ -78,35 +78,35 @@ contract ODSaviour is Authorizable, Modifiable, ModifiablePerCollateral, IODSavi
}
if (!_enabledVaults[_vaultId]) revert VaultNotAllowed(_vaultId);

uint256 _reqCollateral;
uint256 _requiredCollateral;
{
ISAFEEngine.SAFEEngineCollateralData memory _safeEngCData = safeEngine.cData(_cType);

(uint256 _currCollateral, uint256 _currDebt) = getCurrentCollateralAndDebt(_cType, _safe);
(uint256 _currentCollateral, uint256 _currentDebt) = getCurrentCollateralAndDebt(_cType, _safe);
uint256 _accumulatedRate = _safeEngCData.accumulatedRate;
uint256 _liquidationPrice = _safeEngCData.liquidationPrice;
uint256 _safetyPrice = _safeEngCData.safetyPrice;

uint256 _collatXliqPrice = _currCollateral.wmul(_liquidationPrice);
uint256 _debtXaccumuRate = _currDebt.wmul(_accumulatedRate);
uint256 _collateralXliquidationPrice = _currentCollateral.wmul(_liquidationPrice);
uint256 _debtXaccumulatedRate = _currentDebt.wmul(_accumulatedRate);

_reqCollateral = (_debtXaccumuRate - _collatXliqPrice).wdiv(_safetyPrice);
uint256 _newCollatXliqPrice = (_reqCollateral + _currCollateral).wmul(_liquidationPrice);
_requiredCollateral = (_debtXaccumulatedRate - _collateralXliquidationPrice).wdiv(_safetyPrice);
uint256 _newCollateralXliquidationPrice = (_requiredCollateral + _currentCollateral).wmul(_liquidationPrice);

if (_newCollatXliqPrice <= _debtXaccumuRate) revert SafetyRatioNotMet();
if (_newCollateralXliquidationPrice <= _debtXaccumulatedRate) revert SafetyRatioNotMet();
}
IERC20 _token = _saviourTokenAddresses[_cType];
_token.transferFrom(saviourTreasury, address(this), _reqCollateral);
_token.transferFrom(saviourTreasury, address(this), _requiredCollateral);

if (_token.balanceOf(address(this)) >= _reqCollateral) {
if (_token.balanceOf(address(this)) >= _requiredCollateral) {
address _collateralJoin = collateralJoinFactory.collateralJoins(_cType);
_token.approve(_collateralJoin, _reqCollateral);
ICollateralJoin(_collateralJoin).join(_safe, _reqCollateral);
safeManager.modifySAFECollateralization(_vaultId, int256(_reqCollateral), int256(0), false);
_collateralAdded = _reqCollateral;
_token.approve(_collateralJoin, _requiredCollateral);
ICollateralJoin(_collateralJoin).join(_safe, _requiredCollateral);
safeManager.modifySAFECollateralization(_vaultId, int256(_requiredCollateral), int256(0), false);
_collateralAdded = _requiredCollateral;
_liquidatorReward = liquidatorReward;

emit SafeSaved(_vaultId, _reqCollateral);
emit SafeSaved(_vaultId, _requiredCollateral);
_ok = true;
} else {
_ok = false;
Expand All @@ -117,10 +117,10 @@ contract ODSaviour is Authorizable, Modifiable, ModifiablePerCollateral, IODSavi
function getCurrentCollateralAndDebt(
bytes32 _cType,
address _safe
) public view returns (uint256 _currCollateral, uint256 _currDebt) {
) public view returns (uint256 _currentCollateral, uint256 _currentDebt) {
ISAFEEngine.SAFE memory _safeData = safeEngine.safes(_cType, _safe);
_currCollateral = _safeData.lockedCollateral;
_currDebt = _safeData.generatedDebt;
_currentCollateral = _safeData.lockedCollateral;
_currentDebt = _safeData.generatedDebt;
}

function _initializeCollateralType(bytes32 _cType, bytes memory _collateralParams) internal virtual override {
Expand Down
99 changes: 87 additions & 12 deletions test/e2e/E2ESaviour.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -436,7 +436,6 @@ contract E2ESaviourTestLiquidateAndSave is E2ESaviourTestLiquidateSetup {
}
}

/// todo clean up and refactor to remove duplicate code in other setups
contract E2ESaviourTestFuzz is E2ESaviourTestRiskSetup {
using Math for uint256;

Expand Down Expand Up @@ -476,8 +475,6 @@ contract E2ESaviourTestFuzz is E2ESaviourTestRiskSetup {

function _devalueCollateral(uint256 _devaluation) internal {
uint256 _tknPrice = tknOracle.read();
emit log_named_uint('TKN Price', _tknPrice);
emit log_named_uint('DEVAL Price', _devaluation);
tknOracle.setPriceAndValidity(_tknPrice - _devaluation, true);
_setAndRefreshData();
oracleRelayer.updateCollateralPrice(TKN);
Expand All @@ -489,21 +486,20 @@ contract E2ESaviourTestFuzz is E2ESaviourTestRiskSetup {
_devalueCollateral(_devaluation);

ISAFEEngine.SAFEEngineCollateralData memory _safeEngCData = safeEngine.cData(TKN);
ISAFEEngine.SAFE memory _safeData = safeEngine.safes(TKN, aliceNFV.safeHandler);

(uint256 _currCollateral, uint256 _currDebt) = saviour.getCurrentCollateralAndDebt(TKN, aliceNFV.safeHandler);
(uint256 _currentCollateral, uint256 _currentDebt) = saviour.getCurrentCollateralAndDebt(TKN, aliceNFV.safeHandler);
uint256 _accumulatedRate = _safeEngCData.accumulatedRate;
uint256 _liquidationPrice = _safeEngCData.liquidationPrice;
uint256 _safetyPrice = _safeEngCData.safetyPrice;
emit log_named_uint('Safety Price', 10);

uint256 _collatXliqPrice = _currCollateral.wmul(_liquidationPrice);
uint256 _debtXaccumuRate = _currDebt.wmul(_accumulatedRate);
uint256 _collateralXliquidationPrice = _currentCollateral.wmul(_liquidationPrice);
uint256 _debtXaccumulatedRate = _currentDebt.wmul(_accumulatedRate);

if (_collatXliqPrice < _debtXaccumuRate) {
uint256 _reqAmount = (_debtXaccumuRate - _collatXliqPrice).wdiv(_safetyPrice);
uint256 _newCollatXliqPrice = (_currCollateral + _reqAmount).wmul(_liquidationPrice);

assertTrue(_newCollatXliqPrice > _debtXaccumuRate);
if (_collateralXliquidationPrice < _debtXaccumulatedRate) {
uint256 _requiredAmount = (_debtXaccumulatedRate - _collateralXliquidationPrice).wdiv(_safetyPrice);
uint256 _newCollateralXliquidationPrice = (_currentCollateral + _requiredAmount).wmul(_liquidationPrice);
assertTrue(_newCollateralXliquidationPrice > _debtXaccumulatedRate);
}
}

Expand Down Expand Up @@ -545,4 +541,83 @@ contract E2ESaviourTestFuzz is E2ESaviourTestRiskSetup {
assertTrue(_collateralC == _collateralA && _debtC == _debtA);
}
}

/**
* @dev `emit log_named_[dataType]` does not work for fuzz tests, only static tests
* static tests added below for logging outputs
*/
function test_algorithm_static() public {
uint256 _devaluation = 0.15 ether;
_devalueCollateral(_devaluation);

ISAFEEngine.SAFEEngineCollateralData memory _safeEngCData = safeEngine.cData(TKN);

(uint256 _currentCollateral, uint256 _currentDebt) = saviour.getCurrentCollateralAndDebt(TKN, aliceNFV.safeHandler);
emit log_named_uint('_currentCollateral ------------', _currentCollateral);
emit log_named_uint('_currentDebt ------------------', _currentDebt);

uint256 _accumulatedRate = _safeEngCData.accumulatedRate;
uint256 _liquidationPrice = _safeEngCData.liquidationPrice;
uint256 _safetyPrice = _safeEngCData.safetyPrice;
emit log_named_uint('_accumulatedRate --------------', _accumulatedRate);
emit log_named_uint('_liquidationPrice -------------', _liquidationPrice);
emit log_named_uint('_safetyPrice ------------------', _safetyPrice);

uint256 _collateralXliquidationPrice = _currentCollateral.wmul(_liquidationPrice);
uint256 _debtXaccumulatedRate = _currentDebt.wmul(_accumulatedRate);
emit log_named_uint('_collateralXliquidationPrice --', _collateralXliquidationPrice);
emit log_named_uint('_debtXaccumulatedRate ---------', _debtXaccumulatedRate);

if (_collateralXliquidationPrice < _debtXaccumulatedRate) {
uint256 _requiredAmount;

/// @notice scoped to reduce stack
{
uint256 _collateralDeficit = (_debtXaccumulatedRate - _collateralXliquidationPrice).wdiv(_safetyPrice);
emit log_named_uint('_collateralDeficit ------------', _collateralDeficit);

uint256 _safetyCollateral = _collateralXliquidationPrice.wdiv(_safetyPrice);
emit log_named_uint('_safetyCollateral -------------', _safetyCollateral);

_requiredAmount = _collateralDeficit + _safetyCollateral - _currentCollateral;
emit log_named_uint('_requiredAmount ---------------', _requiredAmount);
}

uint256 _newCollateralXliquidationPrice = (_currentCollateral + _requiredAmount).wmul(_liquidationPrice);
emit log_named_uint('_newCollateralXliquidationPrice', _newCollateralXliquidationPrice);

assertTrue(_newCollateralXliquidationPrice > _debtXaccumulatedRate);

/// @notice compare to ratio using NFTRenderer formatted ratios
emit log_named_uint('_safetyCRatio -----------------', oracleRelayer.cParams(TKN).safetyCRatio / 1e18);
emit log_named_uint('_liquidationCRatio ------------', oracleRelayer.cParams(TKN).liquidationCRatio / 1e18);

/// @notice `_ratio` should approximately equal `_safetyCRatio`
emit log_named_uint(
'_ratio ------------------------',
(
((_currentCollateral + _requiredAmount).wmul(oracleRelayer.cParams(TKN).oracle.read())).wdiv(
_debtXaccumulatedRate
)
)
);
}
}

function test_liquidateProtectedSafe_static() public {
uint256 _devaluation = 0.15 ether;
(uint256 _collateralA, uint256 _debtA) = saviour.getCurrentCollateralAndDebt(TKN, aliceNFV.safeHandler);
assertTrue(_collateralA > 0 && _debtA > 0);
assertTrue((_collateralA * liquidationPrice) >= (_debtA * accumulatedRate));

_devalueCollateral(_devaluation);
(uint256 _collateralB, uint256 _debtB) = saviour.getCurrentCollateralAndDebt(TKN, aliceNFV.safeHandler);
if (liquidationPrice != 0 && (_collateralB * liquidationPrice) < (_debtB * accumulatedRate)) {
liquidationEngine.liquidateSAFE(TKN, aliceNFV.safeHandler);
}
(uint256 _collateralC, uint256 _debtC) = saviour.getCurrentCollateralAndDebt(TKN, aliceNFV.safeHandler);
assertTrue(_collateralC >= _collateralA);
assertEq(_debtC, _debtA);
emit log_named_uint('x', _collateralA);
}
}

0 comments on commit b5e337d

Please sign in to comment.