Skip to content

Commit

Permalink
WIP reaper v2 O(1) debtAssetId
Browse files Browse the repository at this point in the history
  • Loading branch information
massun-onibakuchi committed May 30, 2024
1 parent 9fe05c9 commit ce51e6e
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 22 deletions.
30 changes: 16 additions & 14 deletions src/OptimizedGrimReaper.sol
Original file line number Diff line number Diff line change
Expand Up @@ -105,37 +105,39 @@ contract OptimizedGrimReaper {
}
}

/// @notice Supports only 3 collateral assets
/// @notice Supports only 3 collateral & debt assets
contract OptimizedGrimReaperV2 is OptimizedGrimReaper {
uint256 constant COLLATERAL_ASSETS_TABLE_OFFSET = 0x0C + 0x14 * 3; // 0x0C +0x14 * [number of supported collateral assetss]

/// @dev At deployment, the table of collateral assets must be appended to the runtime code of this contract
/// `bytes.concat(type(OptimizedGrimReaperV2).runtimeCode, collateralAssetsTable)`
/// where `collateralAssetsTable` is a table of collateral assets to be used in the liquidation call
/// The table must be in the format of: `abi.encodePacked(address[] collateralAssets)`
/// @dev At deployment, the table of tokens must be appended to the runtime code of this contract
/// `bytes.concat(type(OptimizedGrimReaperV2).runtimeCode, tokens)`
/// where `tokens` is a table of collateral tokens to be used in the liquidation call
/// The table must be in the format of: `abi.encodePacked(address[] tokens)`
constructor() {}

/// @custom:param data Custom encoded data for `liquidationCall`
/// @dev abi.encodePacked(address _debt, uint8 collateralId, address _user, uint128 _debtToCover)
/// where `collateralId` is the index of the collateral asset in the table appended to the runtime code on deployment
/// @dev abi.encodePacked(uint8 collateralId, uint8 debtAssetId, address _user, uint128 _debtToCover)
/// where id is the index of the collateral asset in the table appended to the runtime code on deployment
fallback() external payable override {
assembly {
// only the owner of this contract is allowed to call this function
if iszero(eq(caller(), OWNER)) { revert(0, 0) }

// We don't have function signatures sweet saving EVEN MORE GAS

let debtAsset := shr(0x58, calldataload(0x00)) // bytes21 (address debtAsset, bytes1 collateralId)
let collateralId := and(debtAsset, 0xff)
debtAsset := shr(0x08, debtAsset) // Remove the last byte and get the address
let user := shr(0x50, calldataload(0x00)) // bytes22 (address user, bytes1 collateralId, bytes1 debtAssetId)
let collateralId := and(shr(0x08, user), 0xff)
let debtAssetId := and(user, 0x00ff)
// bytes20
let user := shr(0x60, calldataload(0x15))
user := shr(0x10, user)
// uint128
let debtToCover := shr(0x80, calldataload(0x29))
let debtToCover := shr(0x80, calldataload(0x16))

// Call debtAsset.approve(pool, debtToCover)

// approve function signature
// Copy the collateral asset from the table
codecopy(0x00, add(sub(codesize(), COLLATERAL_ASSETS_TABLE_OFFSET), mul(debtAssetId, 0x14)), 0x20)
let debtAsset := mload(0x00)
mstore(0x14, POOL)
mstore(0x34, add(debtToCover, 0x01))
mstore(0x00, 0x095ea7b3000000000000000000000000) // `approve(address,uint256)`.
Expand All @@ -146,7 +148,7 @@ contract OptimizedGrimReaperV2 is OptimizedGrimReaper {

// Copy the collateral asset from the table
codecopy(0x14, add(sub(codesize(), COLLATERAL_ASSETS_TABLE_OFFSET), mul(collateralId, 0x14)), 0x20)
mstore(0x34, debtAsset)
mstore(0x34, shr(0x60, shl(0x60, debtAsset)))
mstore(0x00, 0x00a718a9000000000000000000000000)
mstore(0x54, user)
mstore(0x74, debtToCover)
Expand Down
22 changes: 14 additions & 8 deletions test/GrimReaper.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ abstract contract GrimReaperBaseTest is Test {
GrimReaper public reaper;

MockERC20 collateral = MockERC20(0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48);
MockERC20 debt;
MockERC20 debt = MockERC20(0x5f98805A4E8be255a32880FDeC7F6728C6568bA0);
MockPool pool = MockPool(POOL);

uint256 liquidationBonus = 10000;
Expand All @@ -25,7 +25,8 @@ abstract contract GrimReaperBaseTest is Test {
function setUp() public virtual {
MockERC20 _token = new MockERC20();
vm.etch(address(collateral), address(_token).code);
debt = new MockERC20();
vm.etch(address(debt), address(_token).code);

MockPool _pool = new MockPool();
vm.etch(POOL, address(_pool).code);

Expand Down Expand Up @@ -161,17 +162,22 @@ contract OptimizedGrimReaperSolV2Test is OptimizedGrimReaperSolTest {
override
returns (bytes memory payload)
{
uint8 id;
if (_col == 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2) {
uint8 colId = convertTokenToId(_col);
uint8 debtId = convertTokenToId(_debt);

payload = abi.encodePacked(_user, uint8(colId), uint8(debtId), uint128(_debtToCover));
}

function convertTokenToId(address token) internal pure returns (uint8 id) {
if (token == 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2) {
id = 0;
} else if (_col == 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48) {
} else if (token == 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48) {
id = 1;
} else if (_col == 0x5f98805A4E8be255a32880FDeC7F6728C6568bA0) {
} else if (token == 0x5f98805A4E8be255a32880FDeC7F6728C6568bA0) {
id = 2;
} else {
revert("invalid collateral");
revert("token is not supported");
}
payload = abi.encodePacked(_debt, uint8(id), _user, uint128(_debtToCover));
}
}

Expand Down

0 comments on commit ce51e6e

Please sign in to comment.