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

Gas optimizations in storage structs #10

Merged
merged 2 commits into from
Mar 25, 2022
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
12 changes: 12 additions & 0 deletions .gas-snapshot
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
OptionSettlementTest:testExercise() (gas: 182892)
OptionSettlementTest:testFailDuplicateChain() (gas: 13642)
OptionSettlementTest:testFailExercise(uint112,uint112) (runs: 256, μ: 88228, ~: 111289)
OptionSettlementTest:testFailUri() (gas: 7693)
OptionSettlementTest:testFuzzExercise(uint112,uint112) (runs: 256, μ: 210415, ~: 217421)
OptionSettlementTest:testFuzzNewChain(uint160,uint96,uint96,uint40,uint40) (runs: 256, μ: 159428, ~: 159428)
OptionSettlementTest:testFuzzRedeem(uint112) (runs: 256, μ: 146653, ~: 146655)
OptionSettlementTest:testFuzzWrite(uint112) (runs: 256, μ: 174449, ~: 174449)
OptionSettlementTest:testNewChain() (gas: 148239)
OptionSettlementTest:testRedeem() (gas: 134716)
OptionSettlementTest:testUri() (gas: 10245)
OptionSettlementTest:testWrite() (gas: 170342)
22 changes: 11 additions & 11 deletions src/OptionSettlement.sol
Original file line number Diff line number Diff line change
Expand Up @@ -31,27 +31,27 @@ struct Option {
// The underlying asset to be received
address underlyingAsset;
// The timestamp after which this option may be exercised
uint64 exerciseTimestamp;
uint40 exerciseTimestamp;
// The timestamp before which this option must be exercised
uint40 expiryTimestamp;
// The address of the asset needed for exercise
address exerciseAsset;
// The timestamp before which this option must be exercised
uint64 expiryTimestamp;
// Random seed created at the time of option chain creation
uint256 settlementSeed;
// The amount of the underlying asset contained within an option contract of this type
uint256 underlyingAmount;
uint96 underlyingAmount;
// Random seed created at the time of option chain creation
uint160 settlementSeed;
// The amount of the exercise asset required to exercise this option
uint256 exerciseAmount;
uint96 exerciseAmount;
}

struct Claim {
// Which option was written
uint256 option;
// These are 1:1 contracts with the underlying Option struct
// The number of contracts written in this claim
uint256 amountWritten;
uint112 amountWritten;
// The amount of contracts assigned for exercise to this claim
uint256 amountExercised;
uint112 amountExercised;
// The two amounts above along with the option info, can be used to calculate the underlying assets
bool claimed;
}
Expand Down Expand Up @@ -161,7 +161,7 @@ contract OptionSettlementEngine is ERC1155 {
chainMap[chainKey] = true;
}

function write(uint256 optionId, uint256 amount) external {
function write(uint256 optionId, uint112 amount) external {
require(tokenType[optionId] == Type.Option, "Token is not an option");
require(
option[optionId].settlementSeed != 0,
Expand Down Expand Up @@ -199,7 +199,7 @@ contract OptionSettlementEngine is ERC1155 {
tokens[1] = claimId;

uint256[] memory amounts = new uint256[](2);
amounts[0] = amount;
amounts[0] = uint256(amount);
amounts[1] = 1;

bytes memory data = new bytes(0);
Expand Down
70 changes: 35 additions & 35 deletions src/test/OptionSettlement.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -76,11 +76,11 @@ contract OptionSettlementTest is DSTest, NFTreceiver {
Option memory info = Option({
underlyingAsset: address(weth),
exerciseAsset: address(dai),
settlementSeed: 1,
underlyingAmount: 1 ether,
exerciseAmount: 3000 ether,
exerciseTimestamp: uint64(block.timestamp),
expiryTimestamp: (uint64(block.timestamp) + 604800)
settlementSeed: uint160(1),
underlyingAmount: uint96(1 ether),
exerciseAmount: uint96(3000 ether),
exerciseTimestamp: uint40(block.timestamp),
expiryTimestamp: (uint40(block.timestamp) + 604800)
});
engine.newChain(info);

Expand All @@ -106,31 +106,31 @@ contract OptionSettlementTest is DSTest, NFTreceiver {
Option memory info = Option({
underlyingAsset: address(weth),
exerciseAsset: address(dai),
settlementSeed: 0,
underlyingAmount: 1 ether,
exerciseAmount: 3100 ether,
exerciseTimestamp: uint64(block.timestamp),
expiryTimestamp: (uint64(block.timestamp) + 604800)
settlementSeed: uint160(1),
underlyingAmount: uint96(1 ether),
exerciseAmount: uint96(3100 ether),
exerciseTimestamp: uint40(block.timestamp),
expiryTimestamp: (uint40(block.timestamp) + 604800)
});

uint256 tokenId = engine.newChain(info);

(
,
uint64 testExerciseTimestamp,
uint40 testExerciseTimestamp,
uint40 testExpiryTimestamp,
,
uint64 testExpiryTimestamp,
uint256 testSettlementSeed,
uint256 testUnderlyingAmount,
uint256 testExerciseAmount
uint96 testUnderlyingAmount,
uint160 testSettlementSeed,
uint96 testExerciseAmount
) = engine.option(nextTokenId);

assertTrue(engine.chainMap(keccak256(abi.encode(info))));
assertEq(engine.nextTokenId(), nextTokenId + 1);
assertEq(tokenId, engine.nextTokenId() - 1);

assertEq(testExerciseTimestamp, uint64(block.timestamp));
assertEq(testExpiryTimestamp, (uint64(block.timestamp) + 604800));
assertEq(testExerciseTimestamp, uint40(block.timestamp));
assertEq(testExpiryTimestamp, (uint40(block.timestamp) + 604800));
assertEq(testUnderlyingAmount, 1 ether);
assertEq(testExerciseAmount, 3100 ether);
assertEq(testSettlementSeed, 42);
Expand All @@ -140,19 +140,19 @@ contract OptionSettlementTest is DSTest, NFTreceiver {
}

function testFuzzNewChain(
uint256 settlementSeed,
uint256 underlyingAmount,
uint256 exerciseAmount,
uint64 exerciseTimestamp,
uint64 expiryTimestamp
uint160 settlementSeed,
uint96 underlyingAmount,
uint96 exerciseAmount,
uint40 exerciseTimestamp,
uint40 expiryTimestamp
) public {
uint256 nextTokenId = engine.nextTokenId();

VM.assume(expiryTimestamp >= block.timestamp + 86400);
VM.assume(exerciseTimestamp >= block.timestamp);
VM.assume(exerciseTimestamp <= expiryTimestamp - 86400);
VM.assume(expiryTimestamp <= type(uint64).max);
VM.assume(exerciseTimestamp <= type(uint64).max);
VM.assume(expiryTimestamp <= type(uint40).max);
VM.assume(exerciseTimestamp <= type(uint40).max);
VM.assume(underlyingAmount <= wethTotalSupply);
VM.assume(exerciseAmount <= daiTotalSupply);
VM.assume(type(uint256).max - underlyingAmount >= wethTotalSupply);
Expand All @@ -172,12 +172,12 @@ contract OptionSettlementTest is DSTest, NFTreceiver {

(
,
uint64 testExerciseTimestamp,
uint40 testExerciseTimestamp,
uint40 testExpiryTimestamp,
,
uint64 testExpiryTimestamp,
uint256 testSettlementSeed,
uint256 testUnderlyingAmount,
uint256 testExerciseAmount
uint96 testUnderlyingAmount,
uint160 testSettlementSeed,
uint96 testExerciseAmount
) = engine.option(nextTokenId);

assertTrue(engine.chainMap(keccak256(abi.encode(info))));
Expand All @@ -202,8 +202,8 @@ contract OptionSettlementTest is DSTest, NFTreceiver {
settlementSeed: 1,
underlyingAmount: 1 ether,
exerciseAmount: 3000 ether,
exerciseTimestamp: uint64(block.timestamp),
expiryTimestamp: (uint64(block.timestamp) + 604800)
exerciseTimestamp: uint40(block.timestamp),
expiryTimestamp: (uint40(block.timestamp) + 604800)
});
engine.newChain(info);
}
Expand Down Expand Up @@ -259,7 +259,7 @@ contract OptionSettlementTest is DSTest, NFTreceiver {
assertTrue(true);
}

function testFuzzWrite(uint256 amountWrite) public {
function testFuzzWrite(uint112 amountWrite) public {
uint256 nextTokenId = engine.nextTokenId();
uint256 wethBalanceEngine = IERC20(weth).balanceOf(address(engine));
uint256 wethFeeTo = IERC20(weth).balanceOf(address(engine.feeTo()));
Expand Down Expand Up @@ -345,7 +345,7 @@ contract OptionSettlementTest is DSTest, NFTreceiver {
assertEq(engine.balanceOf(address(this), 1), 1);
}

function testFuzzExercise(uint256 amountWrite, uint256 amountExercise)
function testFuzzExercise(uint112 amountWrite, uint112 amountExercise)
public
{
// TODO(add checks after updating exercise())
Expand Down Expand Up @@ -405,7 +405,7 @@ contract OptionSettlementTest is DSTest, NFTreceiver {
assertEq(engine.balanceOf(address(this), 1), 1);
}

function testFailExercise(uint256 amountWrite, uint256 amountExercise)
function testFailExercise(uint112 amountWrite, uint112 amountExercise)
public
{
VM.assume(amountExercise > amountWrite);
Expand Down Expand Up @@ -441,7 +441,7 @@ contract OptionSettlementTest is DSTest, NFTreceiver {
if (engine.tokenType(1) == Type.None) assertTrue(true);
}

function testFuzzRedeem(uint256 amountWrite) public {
function testFuzzRedeem(uint112 amountWrite) public {
// TODO(add checks after updating exercise())
uint256 wethBalanceEngine = IERC20(weth).balanceOf(address(engine));
uint256 daiBalanceEngine = IERC20(dai).balanceOf(address(engine));
Expand Down