Skip to content

Commit

Permalink
Event architecture and implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
0xAlcibiades authored Mar 27, 2022
2 parents 8e3bf6f + e14ae1d commit 47f7599
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 20 deletions.
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

0 comments on commit 47f7599

Please sign in to comment.