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

Event architecture and implementation #24

Merged
merged 2 commits into from
Mar 27, 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
68 changes: 48 additions & 20 deletions src/OptionSettlement.sol
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import "solmate/utils/SafeTransferLib.sol";
// TODO(Consider converting require strings to errors for gas savings)
// TODO(Branch later for non harmony VRF support)
// TODO(Event design, architecture, implementation)
// TODO(Adding a fee sweep mechanism rather than on every operation would save gas)
// TODO(DRY code)
// TODO(Optimize)
// TODO(Gas optimized fees struct?)
Expand Down Expand Up @@ -76,21 +75,32 @@ contract OptionSettlementEngine is IOptionSettlementEngine, ERC1155 {
feeTo = newFeeTo;
}

// TODO(Consider keeper here)
// TODO(Test)
function sweepFees(address[] memory tokens) public {
address sendFeeTo = feeTo;
address token;
uint256 fee;
uint256 sweep;
uint256 numTokens = tokens.length;

unchecked {
uint256 numTokens = tokens.length;
for (uint256 i = 0; i < numTokens; i++) {
uint256 fee = feeBalance[tokens[i]];
// TODO(Leave 1 wei here as a gas optimization)
if (fee > 0) {
SafeTransferLib.safeTransfer(ERC20(tokens[i]), feeTo, fee);
feeBalance[tokens[i]] = 0;
// Get the token and balance to sweep
token = tokens[i];

fee = feeBalance[token];
// Leave 1 wei here as a gas optimization
if (fee > 1) {
sweep = feeBalance[token] - 1;
SafeTransferLib.safeTransfer(
ERC20(token),
sendFeeTo,
sweep
);
feeBalance[token] = 1;
emit FeeSwept(token, sendFeeTo, sweep);
}
}
}
// TODO(Emit event about fees collected)
}

// https://docs.harmony.one/home/developers/tools/harmony-vrf
Expand Down Expand Up @@ -173,13 +183,21 @@ contract OptionSettlementEngine is IOptionSettlementEngine, ERC1155 {

_option[nextTokenId] = optionInfo;

// TODO(This should emit an event about the creation for indexing in a graph)

optionId = nextTokenId;

// Increment the next token id to be used
++nextTokenId;
hashToOptionToken[chainKey] = optionId;

emit NewChain(
optionId,
optionInfo.exerciseAsset,
optionInfo.underlyingAsset,
optionInfo.exerciseAmount,
optionInfo.underlyingAmount,
optionInfo.exerciseTimestamp,
optionInfo.expiryTimestamp
);
}

function write(uint256 optionId, uint112 amount)
Expand Down Expand Up @@ -233,20 +251,20 @@ contract OptionSettlementEngine is IOptionSettlementEngine, ERC1155 {
});
unexercisedClaimsByOption[optionId].push(claimId);

// TODO(Emit event about fees accrued)
feeBalance[underlyingAsset] += fee;

// TODO(Emit event about the writing)
// Increment the next token ID
++nextTokenId;

emit FeeAccrued(underlyingAsset, msg.sender, fee);
emit OptionsWritten(optionId, msg.sender, claimId, amount);
}

function assignExercise(
uint256 optionId,
uint112 amount,
uint160 settlementSeed
) internal {
// TODO(Fuzz this in testing and flush out any bugs)
// Initial storage pointer
Claim storage claimRecord;

Expand Down Expand Up @@ -300,6 +318,7 @@ contract OptionSettlementEngine is IOptionSettlementEngine, ERC1155 {
} else {
unexercisedClaimsByOption[optionId].pop();
}
// TODO(Emit event about assignment?)

// Increment for the next loop
settlementSeed = uint160(
Expand All @@ -318,11 +337,11 @@ contract OptionSettlementEngine is IOptionSettlementEngine, ERC1155 {
Option storage optionRecord = _option[optionId];

// Require that we have reached the exercise timestamp

require(
optionRecord.exerciseTimestamp <= block.timestamp,
"Too early to exercise"
);

uint256 rxAmount = optionRecord.exerciseAmount * amount;
uint256 txAmount = optionRecord.underlyingAmount * amount;
uint256 fee = ((rxAmount / 10000) * feeBps);
Expand All @@ -345,11 +364,12 @@ contract OptionSettlementEngine is IOptionSettlementEngine, ERC1155 {

assignExercise(optionId, amount, optionRecord.settlementSeed);

// TODO(Emit event about fees accrued)
feeBalance[exerciseAsset] += fee;

_burn(msg.sender, optionId, amount);
// TODO(Emit events for indexing and frontend)

emit FeeAccrued(exerciseAsset, msg.sender, fee);
emit OptionsExercised(optionId, msg.sender, amount);
}

function redeem(uint256 claimId) external {
Expand Down Expand Up @@ -393,9 +413,17 @@ contract OptionSettlementEngine is IOptionSettlementEngine, ERC1155 {

claimRecord.claimed = true;

// TODO(Emit events for indexing and frontend)

_burn(msg.sender, claimId, 1);

emit ClaimRedeemed(
claimId,
optionId,
msg.sender,
optionRecord.exerciseAsset,
optionRecord.underlyingAsset,
uint96(exerciseAmount),
uint96(underlyingAmount)
);
}

function underlying(uint256 tokenId)
Expand Down
45 changes: 45 additions & 0 deletions src/interfaces/IOptionSettlementEngine.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,51 @@ pragma solidity 0.8.11;

// @author 0xAlcibiades
interface IOptionSettlementEngine {
event FeeSwept(
address indexed token,
address indexed feeTo,
uint256 amount
);

event NewChain(
uint256 indexed optionId,
address indexed exerciseAsset,
address indexed underlyingAsset,
uint96 exerciseAmount,
uint96 underlyingAmount,
uint40 exerciseTimestamp,
uint40 expiryTimestamp
);

event OptionsExercised(
uint256 indexed optionId,
address indexed exercisee,
uint112 amount
);

event OptionsWritten(
uint256 indexed optionId,
address indexed writer,
uint256 claimId,
uint112 amount
);

event FeeAccrued(
address indexed asset,
address indexed payor,
uint256 amount
);

event ClaimRedeemed(
uint256 indexed claimId,
uint256 indexed optionId,
address indexed redeemer,
address exerciseAsset,
address underlyingAsset,
uint96 exerciseAmount,
uint96 underlyingAmount
);

// @dev This enumeration is used to determine the type of an ERC1155 subtoken in the engine.
enum Type {
None,
Expand Down