-
Notifications
You must be signed in to change notification settings - Fork 109
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
parent and child insurance stubs #272
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is the assumption that the signedCommitment
in buy
also encodes the values being committed to alongside the commitment + signature?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah, just pushed up a commit that includes those. the entire struct SequencerCommitment
is signed over
address public immutable childChainContract; | ||
|
||
// D | ||
uint256 public depositedAmount; |
Check failure
Code scanning / Slither
Uninitialized state variables High
- Parent.buy(uint256,Parent.SequencerCommitment,bytes,Parent.RetryableParams)
function buy( | ||
uint256 minSatisfied, | ||
SequencerCommitment calldata commitment, | ||
bytes calldata signature, | ||
RetryableParams calldata retryableParams | ||
) public payable { | ||
// require depositAmount - insuranceSold + minSatisfied >= insuranceAmount | ||
// put this check first because it's the mosy likely to fail without user error | ||
require(depositedAmount - insuranceSold + minSatisfied >= commitment.insuranceAmount, "potential undercollateralization"); | ||
|
||
// verify the signature | ||
require(isValidSignature(commitment, signature), "invalid signature"); | ||
|
||
// require msg.value == insuranceCost + retryableCost | ||
uint256 retryableCost = retryableParams.maxSubmissionCost + retryableParams.gasLimit * retryableParams.gasPrice; | ||
require(msg.value == retryableCost + commitment.insuranceCost, "invalid value"); | ||
|
||
// require !hasUsedCommitment(commitment) | ||
require(!hasUsedCommitment(commitment), "commitment already used"); | ||
|
||
// increment insuranceSold by amount | ||
insuranceSold += commitment.insuranceAmount; | ||
|
||
// mark commitment as used | ||
usedCommitments[hashCommitment(commitment)] = true; | ||
|
||
// build calldata for child contract | ||
bytes memory data = abi.encodeCall( | ||
Child.commit, | ||
( | ||
sequenceNumber, | ||
commitment.beneficiary, | ||
commitment.insuranceAmount, | ||
commitment.blockNum, | ||
commitment.blockHash | ||
) | ||
); | ||
|
||
// create a retryable to hit the child contract settle function, sending msg.value | ||
inbox.createRetryableTicket{value: msg.value}({ | ||
to: childChainContract, | ||
l2CallValue: commitment.insuranceCost, | ||
maxSubmissionCost: retryableParams.maxSubmissionCost, | ||
excessFeeRefundAddress: msg.sender, | ||
callValueRefundAddress: msg.sender, | ||
gasLimit: retryableParams.gasLimit, | ||
maxFeePerGas: retryableParams.gasPrice, | ||
data: data | ||
}); | ||
|
||
// increment seqNum | ||
sequenceNumber++; | ||
} |
Check failure
Code scanning / Slither
Reentrancy vulnerabilities High
External calls:
- inbox.createRetryableTicket{value: msg.value}({to:childChainContract,l2CallValue:commitment.insuranceCost,maxSubmissionCost:retryableParams.maxSubmissionCost,excessFeeRefundAddress:msg.sender,callValueRefundAddress:msg.sender,gasLimit:retryableParams.gasLimit,maxFeePerGas:retryableParams.gasPrice,data:data})
State variables written after the call(s):
- sequenceNumber ++
Parent.sequenceNumber can be used in cross function reentrancies:
- Parent.buy(uint256,Parent.SequencerCommitment,bytes,Parent.RetryableParams)
- Parent.sequenceNumber
function buy( | ||
uint256 minSatisfied, | ||
SequencerCommitment calldata commitment, | ||
bytes calldata signature, | ||
RetryableParams calldata retryableParams | ||
) public payable { | ||
// require depositAmount - insuranceSold + minSatisfied >= insuranceAmount | ||
// put this check first because it's the mosy likely to fail without user error | ||
require(depositedAmount - insuranceSold + minSatisfied >= commitment.insuranceAmount, "potential undercollateralization"); | ||
|
||
// verify the signature | ||
require(isValidSignature(commitment, signature), "invalid signature"); | ||
|
||
// require msg.value == insuranceCost + retryableCost | ||
uint256 retryableCost = retryableParams.maxSubmissionCost + retryableParams.gasLimit * retryableParams.gasPrice; | ||
require(msg.value == retryableCost + commitment.insuranceCost, "invalid value"); | ||
|
||
// require !hasUsedCommitment(commitment) | ||
require(!hasUsedCommitment(commitment), "commitment already used"); | ||
|
||
// increment insuranceSold by amount | ||
insuranceSold += commitment.insuranceAmount; | ||
|
||
// mark commitment as used | ||
usedCommitments[hashCommitment(commitment)] = true; | ||
|
||
// build calldata for child contract | ||
bytes memory data = abi.encodeCall( | ||
Child.commit, | ||
( | ||
sequenceNumber, | ||
commitment.beneficiary, | ||
commitment.insuranceAmount, | ||
commitment.blockNum, | ||
commitment.blockHash | ||
) | ||
); | ||
|
||
// create a retryable to hit the child contract settle function, sending msg.value | ||
inbox.createRetryableTicket{value: msg.value}({ | ||
to: childChainContract, | ||
l2CallValue: commitment.insuranceCost, | ||
maxSubmissionCost: retryableParams.maxSubmissionCost, | ||
excessFeeRefundAddress: msg.sender, | ||
callValueRefundAddress: msg.sender, | ||
gasLimit: retryableParams.gasLimit, | ||
maxFeePerGas: retryableParams.gasPrice, | ||
data: data | ||
}); | ||
|
||
// increment seqNum | ||
sequenceNumber++; | ||
} |
Check warning
Code scanning / Slither
Unused return Medium
No description provided.