Skip to content

Commit

Permalink
finished happy path for safe mod tests.
Browse files Browse the repository at this point in the history
  • Loading branch information
MrDeadCe11 committed May 4, 2024
1 parent 9b631ac commit 2783422
Show file tree
Hide file tree
Showing 3 changed files with 201 additions and 10 deletions.
1 change: 1 addition & 0 deletions test/e2e/Common.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ abstract contract Common is DeployForTest, ODTest {

vm.startPrank(deployer); // no governor on test deployment
accountingEngine.modifyParameters('extraSurplusReceiver', abi.encode(address(0x420)));

vm.stopPrank();
}

Expand Down
208 changes: 199 additions & 9 deletions test/e2e/E2ESafeManager.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,120 @@ import {ProxyUser} from '@test/scopes/ProxyUser.t.sol';
import {IODSafeManager} from '@interfaces/proxies/IODSafeManager.sol';
import {SafeSaviourForForTest} from '@test/mocks/SafeSaviourForTest.sol';

import {HOUR, YEAR} from '@libraries/Math.sol';
import {HOUR, YEAR, RAD, WAD, RAY} from '@libraries/Math.sol';

import {ODProxy} from '@contracts/proxies/ODProxy.sol';
import {ERC20ForTest} from '@test/mocks/ERC20ForTest.sol';
import {ICollateralJoin} from '@interfaces/utils/ICollateralJoin.sol';
import {ISAFEEngine} from '@interfaces/ISAFEEngine.sol';

import 'forge-std/console2.sol';

abstract contract BasicActionsForE2ETests is Common {
function depositCollatAndGenDebt(
bytes32 _cType,
uint256 _safeId,
uint256 _collatAmount,
uint256 _deltaWad,
address _proxy
) public {
bytes memory payload = abi.encodeWithSelector(
basicActions.lockTokenCollateralAndGenerateDebt.selector,
address(safeManager),
address(collateralJoin[_cType]),
address(coinJoin),
_safeId,
_collatAmount,
_deltaWad
);
ODProxy(_proxy).execute(address(basicActions), payload);
}

function genDebt(uint256 _safeId, uint256 _deltaWad, address _proxy) public {
bytes memory payload = abi.encodeWithSelector(
basicActions.generateDebt.selector, address(safeManager), address(coinJoin), _safeId, _deltaWad
);
ODProxy(_proxy).execute(address(basicActions), payload);
}

function allowSafe(address _proxy, uint256 _safeId, address _user, bool _ok) public {
bytes memory payload =
abi.encodeWithSelector(basicActions.allowSAFE.selector, address(safeManager), _safeId, _user, _ok);
ODProxy(_proxy).execute(address(basicActions), payload);
}

function quitSystem(address _proxy, uint256 _safeId) public {
bytes memory payload = abi.encodeWithSelector(basicActions.quitSystem.selector, address(safeManager), _safeId);
ODProxy(_proxy).execute(address(basicActions), payload);
}

function moveSAFE(address _proxy, uint256 _src, uint256 _dst) public {
bytes memory payload = abi.encodeWithSelector(basicActions.moveSAFE.selector, address(safeManager), _src, _dst);
ODProxy(_proxy).execute(address(basicActions), payload);
}

function addSAFE(address _proxy, uint256 _safe) public {
bytes memory payload = abi.encodeWithSelector(basicActions.addSAFE.selector, address(safeManager), _safe);
ODProxy(_proxy).execute(address(basicActions), payload);
}

function removeSAFE(address _proxy, uint256 _safe) public {
bytes memory payload = abi.encodeWithSelector(basicActions.removeSAFE.selector, address(safeManager), _safe);
ODProxy(_proxy).execute(address(basicActions), payload);
}

function protectSAFE(address _proxy, uint256 _safe, address _liquidationEngine, address _saviour) public {
bytes memory payload = abi.encodeWithSelector(
basicActions.protectSAFE.selector, address(safeManager), _safe, _liquidationEngine, _saviour
);
ODProxy(_proxy).execute(address(basicActions), payload);
}

function modifySAFECollateralization(
address _proxy,
uint256 _safeId,
int256 _collateralDelta,
int256 _debtDelta
) public {
bytes memory payload = abi.encodeWithSelector(
basicActions.modifySAFECollateralization.selector, address(safeManager), _safeId, _collateralDelta, _debtDelta
);
ODProxy(_proxy).execute(address(basicActions), payload);
}

function transferCollateral(address _proxy, uint256 _safeId, address _dst, uint256 _deltaWad) public {
bytes memory payload =
abi.encodeWithSelector(basicActions.transferCollateral.selector, address(safeManager), _safeId, _dst, _deltaWad);
ODProxy(_proxy).execute(address(basicActions), payload);
}

function transferInternalCoins(address _proxy, uint256 _safeId, address _dst, uint256 _rad) public {
bytes memory payload =
abi.encodeWithSelector(basicActions.transferInternalCoins.selector, address(safeManager), _safeId, _dst, _rad);
ODProxy(_proxy).execute(address(basicActions), payload);
}

function repayDebt(uint256 _safeId, uint256 _deltaWad, address proxy) public {
bytes memory payload = abi.encodeWithSelector(
basicActions.repayDebt.selector, address(safeManager), address(coinJoin), _safeId, _deltaWad
);
ODProxy(proxy).execute(address(basicActions), payload);
}

function repayAllDebt(uint256 _safeId, address proxy) public {
bytes memory payload =
abi.encodeWithSelector(basicActions.repayAllDebt.selector, address(safeManager), address(coinJoin), _safeId);
ODProxy(proxy).execute(address(basicActions), payload);
}

function openSafe() public returns (uint256 safeId, address proxy) {
bytes memory payload = abi.encodeWithSelector(basicActions.openSAFE.selector, address(safeManager), TKN, proxy);
bytes memory safeData = ODProxy(proxy).execute(address(basicActions), payload);
safeId = abi.decode(safeData, (uint256));
}
}

abstract contract E2ESafeMangerSetUp is Base_CType, Common {
abstract contract E2ESafeMangerSetUp is Base_CType, BasicActionsForE2ETests {
address aliceProxy;
address bobProxy;

Expand All @@ -22,13 +133,12 @@ abstract contract E2ESafeMangerSetUp is Base_CType, Common {

event TransferSAFEOwnership(address indexed _sender, uint256 indexed _safe, address _dst);

function setUp() public virtual override{
function setUp() public virtual override {
super.setUp();
super.setupEnvironment();
aliceProxy = deployOrFind(alice);
aliceSafeId = safeManager.openSAFE(_cType(), aliceProxy);
aliceData = safeManager.safeData(aliceSafeId);

}

function deployOrFind(address owner) public returns (address payable) {
Expand All @@ -41,7 +151,7 @@ abstract contract E2ESafeMangerSetUp is Base_CType, Common {
}

function _cType() internal pure override returns (bytes32) {
return bytes32(abi.encodePacked('CTYPE1'));
return TKN;
}

function _removeDelays() internal {
Expand Down Expand Up @@ -108,14 +218,15 @@ contract E2ESafeManagerTest_ViewFunctions is E2ESafeMangerSetUp {
}

contract E2ESafeManagerTest_TransferOwnership is E2ESafeMangerSetUp {
address testSaviour;
address testSaviour;

function setUp() public override{
function setUp() public override {
super.setUp();
testSaviour = address(new SafeSaviourForForTest());
vm.prank(address(timelockController));
liquidationEngine.connectSAFESaviour(testSaviour);
}
}

function test_TransferSafeOwnership() public {
bobProxy = deployOrFind(bob);
//set safe savior to test savior clearing on transfer
Expand Down Expand Up @@ -170,4 +281,83 @@ contract E2ESafeManagerTest_TransferOwnership is E2ESafeMangerSetUp {
}
}

contract E2ESafeManagerTest_ModifySafeCollateralization is E2ESafeMangerSetUp {}
contract E2ESafeManagerTest_ModifySafeCollateralization is E2ESafeMangerSetUp {
ERC20ForTest internal _token;

struct Scenario {
uint256 mintedCollateral;
uint256 generatedDebt;
uint256 lockedCollateral;
}

function setUp() public override {
super.setUp();
//mint collateral to alice
_token = ERC20ForTest(address(ICollateralJoin(address(collateralJoin[_cType()])).collateral()));
vm.prank(alice);
_token.approve(address(aliceProxy), type(uint256).max);
}

modifier happyPath(Scenario memory _scenario) {
ISAFEEngine.SAFEEngineCollateralParams memory safeEngineParams = safeEngine.cParams(_cType());
ISAFEEngine.SAFEEngineCollateralData memory cData = safeEngine.cData(_cType());

vm.assume(
_scenario.mintedCollateral > 10_000
&& _scenario.mintedCollateral < ((safeEngineParams.debtCeiling / RAY) * (cData.accumulatedRate) / RAD)
);
vm.assume(_scenario.mintedCollateral >= _scenario.lockedCollateral);
_scenario.generatedDebt = bound(
_scenario.generatedDebt,
(_scenario.lockedCollateral * (1 * 100)) / 10_000,
(_scenario.lockedCollateral * (74 * 100)) / 10_000
);
_token.mint(alice, _scenario.mintedCollateral);

_;
}

function _depositAndGen(Scenario memory _scenario) internal {
vm.prank(alice);
depositCollatAndGenDebt(_cType(), aliceSafeId, _scenario.lockedCollateral, _scenario.generatedDebt, aliceProxy);
}

function test_ModifySafeCollateralization_LockCollateral(Scenario memory _scenario) public happyPath(_scenario) {
vm.prank(alice);
depositCollatAndGenDebt(_cType(), aliceSafeId, _scenario.lockedCollateral, 0, aliceProxy);
assertEq(safeEngine.safes(_cType(), aliceData.safeHandler).lockedCollateral, _scenario.lockedCollateral);
assertEq(safeEngine.safes(_cType(), aliceData.safeHandler).generatedDebt, 0);
}

function test_ModifySafeCollateralization_LockCollateral_GenDebt(Scenario memory _scenario)
public
happyPath(_scenario)
{
_depositAndGen(_scenario);
assertEq(safeEngine.safes(_cType(), aliceData.safeHandler).lockedCollateral, _scenario.lockedCollateral);
assertEq(safeEngine.safes(_cType(), aliceData.safeHandler).generatedDebt, _scenario.generatedDebt);
}

function test_ModifySafeCollateralization_RepaySomeDebt(Scenario memory _scenario) public happyPath(_scenario) {
_depositAndGen(_scenario);
uint256 startingDebt = safeEngine.safes(_cType(), aliceData.safeHandler).generatedDebt;
uint256 debtToRepay = startingDebt * 7500 / 1e4;
vm.startPrank(alice);
systemCoin.approve(aliceProxy, type(uint256).max);
repayDebt(aliceSafeId, debtToRepay, aliceProxy);
assertEq(safeEngine.safes(_cType(), aliceData.safeHandler).generatedDebt, startingDebt - debtToRepay);
}

function test_ModifySafeCollateralization_RepayAllDebt(Scenario memory _scenario) public happyPath(_scenario) {
_depositAndGen(_scenario);
// give alice some more system coin to pay off her debt
uint256 totalDebt = safeEngine.safes(_cType(), aliceData.safeHandler).generatedDebt;
uint256 debtToMint = totalDebt - systemCoin.balanceOf(alice);
vm.prank(deployer);
systemCoin.mint(alice, debtToMint);
vm.startPrank(alice);
systemCoin.approve(aliceProxy, type(uint256).max);
repayAllDebt(aliceSafeId, aliceProxy);
assertEq(safeEngine.safes(_cType(), aliceData.safeHandler).generatedDebt, 0);
}
}
2 changes: 1 addition & 1 deletion test/e2e/TestParams.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ pragma solidity 0.8.20;

import '@script/Params.s.sol';

bytes32 constant TKN = bytes32('TKN');
bytes32 constant TKN = bytes32(abi.encodePacked('TKN'));
uint256 constant TEST_ETH_PRICE = 2000e18; // 1 ETH = 1000 OD
uint256 constant TEST_TKN_PRICE = 1e18; // 1 TKN = 1 OD

Expand Down

0 comments on commit 2783422

Please sign in to comment.