Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Seaport od e2e testing #32

Merged
merged 15 commits into from
Jun 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions orders/order-126-1718670312.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
{
"order": {
"parameters": {
"offerer": "0x941E92c9Eff78a2b7217057752cf938040a59aE9",
"zone": "0xcafc335d2f5bd0e929b4edbf526eb74fa4c49924",
"zoneHash": "0x2e84022d4abd1b0d5d91d272d53d7aae7a1f8ccadde7259a2626113abf33b41d",
"startTime": 1718670312,
"endTime": "1718756712",
"orderType": 2,
"offer": [
{
"itemType": 2,
"token": "0x05AC7e3ac152012B980407dEff2655c209667E4c",
"identifierOrCriteria": "126",
"startAmount": "1",
"endAmount": "1"
}
],
"consideration": [
{
"itemType": 1,
"token": "0x3018EC2AD556f28d2c0665d10b55ebfa469fD749",
"identifierOrCriteria": "0",
"startAmount": "1000000",
"endAmount": "1000000",
"recipient": "0x941E92c9Eff78a2b7217057752cf938040a59aE9"
}
],
"totalOriginalConsiderationItems": 1,
"salt": "0x0000000000000000000000000000000000000000000000004310248ef0278195",
"conduitKey": "0x0000000000000000000000000000000000000000000000000000000000000000",
"counter": "0"
},
"signature": "0xee700edca211472b65e85d7d93afea9173ac8be03de3943d05c764df3919a8a6a53a1dde2e0a69ed2f60e9fed03a1835aad3a1a7b1e2c8e2e3952e9a73836542"
},
"extraData": "0x05000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000005ac7e3ac152012b980407deff2655c209667e4c000000000000000000000000578078f2e819d66b0d2ffe273260abc247710795000000000000000000000000000000000000000000000000000000000000007e000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000001800000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002b2527ad5e3edfee867b1b10ab34d699ac8fb9d070b6b55717d7b6bb991eadb597c8a32867e454951d5e131b20ffa1b900683e04f07ba42e51b6d5116073173b1"
}
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
"lint:check": "yarn lint:sol && forge fmt --check",
"lint:fix": "sort-package-json && forge fmt && yarn lint:sol --fix",
"lint:sol": "cross-env solhint 'src/**/*.sol' 'test/**/*.sol'",
"test": "FOUNDRY_FUZZ_RUNS=128 FOUNDRY_FUZZ_MAX_TEST_REJECTS=1000000 forge test -vvv --ffi ",
"test": "FOUNDRY_FUZZ_RUNS=64 FOUNDRY_FUZZ_MAX_TEST_REJECTS=1000 forge test -vvv --ffi ",
"test:coverage": "forge coverage --report lcov && lcov --ignore-errors unused --remove lcov.info 'node_modules/*' 'script/*' 'test/*' 'src/contracts/for-test/*' 'src/libraries/*' -o lcov.info.pruned && mv lcov.info.pruned lcov.info && genhtml -o coverage-report lcov.info",
"generate-types": "npx typechain --target ethers-v6 'out/Vault721.sol/Vault721.json' 'out/Vault721Adapter.sol/Vault721Adapter.json' 'out/EncodeSubstandard5ForEthers.sol/EncodeSubstandard5ForEthers.json' --show-stack-traces"
},
Expand All @@ -48,4 +48,4 @@
"engines": {
"node": ">=20.0.0"
}
}
}
8 changes: 6 additions & 2 deletions src/sips/SIP15Decoder.sol
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ library SIP15Decoder {
pure
returns (uint8, address, uint256, bytes32, bytes32)
{
return _decodeSingleTraitsWithOffset(extraData, 0);
return _decodeSingleTraitsWithOffset(extraData, 1);
}

function decodeSubstandard2(bytes calldata extraData)
Expand Down Expand Up @@ -60,7 +60,11 @@ library SIP15Decoder {
function _decodeSingleTraitsWithOffset(
bytes calldata extraData,
uint256 sip15DataStartRelativeOffset
) internal pure returns (uint8, address, uint256, bytes32, bytes32) {
)
internal
pure
returns (uint8 comparisonEnum, address token, uint256 identifier, bytes32 traitValue, bytes32 traitKey)
{
return abi.decode(extraData[sip15DataStartRelativeOffset:], (uint8, address, uint256, bytes32, bytes32));
}
}
100 changes: 6 additions & 94 deletions src/sips/SIP15Encoder.sol
Original file line number Diff line number Diff line change
Expand Up @@ -16,99 +16,11 @@ struct Substandard5Comparison {

library SIP15Encoder {
/**
* @notice Generate a zone hash for an SIP15 contract that implements substandards 1 and/or 2, which
* derives its zoneHash from a single comparison enum, trait value and trait key
* @param zoneParameters the zone parameters for the order being encoded
* @param traitKey the bytes32 encoded trait key for checking a trait on an ERC7496 token
*/
function generateZoneHashForSubstandard1Efficient(
ZoneParameters memory zoneParameters,
bytes32 traitKey
) internal pure returns (bytes32) {
// Get the token address from the first consideration item
address token = zoneParameters.consideration[0].token;
// Get the id from the first consideration item
uint256 identifier = zoneParameters.consideration[0].identifier;

return keccak256(abi.encodePacked(uint8(0), token, identifier, bytes32(0), traitKey));
}
/**
* @notice Generate a zone hash for an SIP15 contract that implements substandard 1, which
* derives its zoneHash from the first offer item, a single comparison enum, trait value and trait key
* @param zoneParameters the zone parameters for the order being encoded
* @param comparisonEnum the comparison enum 0 - 5
* @param traitValue the expected value of the trait.
* @param traitKey the bytes32 encoded trait key for checking a trait on an ERC7496 token
* @notice Generate a zone hash for an SIP15 contract,
* @param encodedData the SIP15 encoded extra data
*/

function generateZoneHashForSubstandard1(
ZoneParameters memory zoneParameters,
uint8 comparisonEnum,
bytes32 traitValue,
bytes32 traitKey
) internal pure returns (bytes32) {
// Get the token address from the first offer item
address token = zoneParameters.offer[0].token;
// Get the id from the first offer item
uint256 identifier = zoneParameters.offer[0].identifier;
return keccak256(abi.encodePacked(comparisonEnum, token, identifier, traitValue, traitKey));
}

/**
* @notice Generate a zone hash for an SIP15 contract that implements substandard 1, which
* derives its zoneHash from the first consideration item, a single comparison enum, trait value and trait key
* @param zoneParameters the zone parameters for the order being encoded
* @param comparisonEnum the comparison enum 0 - 5
* @param traitValue the expected value of the trait.
* @param traitKey the bytes32 encoded trait key for checking a trait on an ERC7496 token
*/
function generateZoneHashForSubstandard2(
ZoneParameters memory zoneParameters,
uint8 comparisonEnum,
bytes32 traitValue,
bytes32 traitKey
) internal pure returns (bytes32) {
// Get the token address from the first consideration item
address token = zoneParameters.consideration[0].token;
// Get the id from the first consideration item
uint256 identifier = zoneParameters.consideration[0].identifier;
return keccak256(abi.encodePacked(comparisonEnum, token, identifier, traitValue, traitKey));
}

function generateZoneHashForSubstandard5(Substandard5Comparison memory _substandard5Comparison)
internal
pure
returns (bytes32)
{
return keccak256(
abi.encodePacked(
_substandard5Comparison.comparisonEnums,
_substandard5Comparison.token,
_substandard5Comparison.traits,
_substandard5Comparison.identifier,
_substandard5Comparison.traitValues,
_substandard5Comparison.traitKeys
)
);
}

/**
* @notice Generate a zone hash for an SIP15 contract that implements substandard 3, which
* derives its zoneHash from a single comparison enum, token address, token id, trait value and trait key
* @param comparisonEnum the comparison enum 0 - 5
* @param token the address of the collection
* @param identifier the tokenId of the token to be checked
* @param traitKey the bytes32 encoded trait key for checking a trait on an ERC7496 token
* @param traitValue the expected value of the trait.
*/
function generateZoneHash(
uint8 comparisonEnum,
address token,
uint256 identifier,
bytes32 traitValue,
bytes32 traitKey
) internal pure returns (bytes32) {
return keccak256(abi.encodePacked(abi.encode(comparisonEnum, token, identifier, traitValue, traitKey)));
function generateZoneHash(bytes memory encodedData) internal pure returns (bytes32) {
return keccak256(abi.encodePacked(encodedData));
}

/**
Expand All @@ -125,7 +37,7 @@ library SIP15Encoder {

// Get the id from the first consideration item
uint256 id = zoneParameters.consideration[0].identifier;
return abi.encodePacked(uint8(0), abi.encode(0, token, id, traitKey, bytes32(0)));
return abi.encodePacked(uint8(0x00), abi.encode(0, token, id, bytes32(0), traitKey));
}

/**
Expand All @@ -146,7 +58,7 @@ library SIP15Encoder {

// Get the id from the first offer item
uint256 id = zoneParameters.offer[0].identifier;
return abi.encodePacked(uint8(0x01), abi.encode(comparisonEnum, token, id, traitKey, traitValue));
return abi.encodePacked(uint8(0x01), abi.encode(comparisonEnum, token, id, traitValue, traitKey));
}

/**
Expand Down
130 changes: 130 additions & 0 deletions test/e2e/SetUp.sol
Original file line number Diff line number Diff line change
@@ -1 +1,131 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.24;

import {DeployForTest, ODTest, COLLAT, DEBT, TKN} from '@opendollar/test/e2e/Common.t.sol';
import {ERC20ForTest} from '@opendollar/test/mocks/ERC20ForTest.sol';
import {ISAFEEngine} from '@opendollar/interfaces/ISAFEEngine.sol';
import {BaseOrderTest} from 'seaport/test/foundry/utils/BaseOrderTest.sol';
import {ODProxy} from '@opendollar/contracts/proxies/ODProxy.sol';
import {IBaseOracle} from '@opendollar/interfaces/oracles/IBaseOracle.sol';

contract SetUp is DeployForTest, ODTest, BaseOrderTest {
uint256 public constant MINT_AMOUNT = 1000 ether;
uint256 public constant MULTIPLIER = 10; // for over collateralization
uint256 public debtCeiling;

address public aliceProxy;
address public bobProxy;

ERC20ForTest public tokenForTest;

function setUp() public virtual override {
super.setUp();
run();

for (uint256 i = 0; i < collateralTypes.length; i++) {
bytes32 _cType = collateralTypes[i];
taxCollector.taxSingle(_cType);
}

vm.label(deployer, 'Deployer');
vm.label(alice, 'Alice');
vm.label(bob, 'Bob');

vm.startPrank(deployer); // no governor on test deployment
accountingEngine.modifyParameters('extraSurplusReceiver', abi.encode(address(alice)));
aliceProxy = deployOrFind(alice);
bobProxy = deployOrFind(bob);
vm.label(aliceProxy, 'AliceProxy');
vm.label(bobProxy, 'BobProxy');

tokenForTest = ERC20ForTest(address(collateral[TKN]));
tokenForTest.mint(MINT_AMOUNT);

ISAFEEngine.SAFEEngineParams memory params = safeEngine.params();
debtCeiling = params.safeDebtCeiling;
}

function deployOrFind(address owner) public returns (address) {
address proxy = vault721.getProxy(owner);
if (proxy == address(0)) {
return address(vault721.build(owner));
} else {
return proxy;
}
}

function _setCollateralPrice(bytes32 _collateral, uint256 _price) internal {
IBaseOracle _oracle = oracleRelayer.cParams(_collateral).oracle;
vm.mockCall(
address(_oracle), abi.encodeWithSelector(IBaseOracle.getResultWithValidity.selector), abi.encode(_price, true)
);
vm.mockCall(address(_oracle), abi.encodeWithSelector(IBaseOracle.read.selector), abi.encode(_price));
oracleRelayer.updateCollateralPrice(_collateral);
}

function _collectFees(bytes32 _cType, uint256 _timeToWarp) internal {
vm.warp(block.timestamp + _timeToWarp);
taxCollector.taxSingle(_cType);
}

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 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 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 depositCollat(bytes32 _cType, uint256 _safeId, uint256 _collatAmount, address _proxy) public {
bytes memory payload = abi.encodeWithSelector(
basicActions.lockTokenCollateral.selector,
address(safeManager),
address(collateralJoin[_cType]),
_safeId,
_collatAmount
);
ODProxy(_proxy).execute(address(basicActions), payload);
}

function freeTokenCollateral(address _proxy, bytes32 _cType, uint256 _safeId, uint256 _deltaWad) public {
bytes memory payload = abi.encodeWithSelector(
basicActions.freeTokenCollateral.selector,
address(safeManager),
address(collateralJoin[_cType]),
_safeId,
_deltaWad
);
ODProxy(_proxy).execute(address(basicActions), payload);
}
}
Loading
Loading