Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
N
nebula
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
exchain
nebula
Commits
38cd9944
Unverified
Commit
38cd9944
authored
May 20, 2024
by
smartcontracts
Committed by
GitHub
May 20, 2024
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: add new CheckSecrets dripcheck (#10479)
parent
2586a82f
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
341 additions
and
0 deletions
+341
-0
CheckSecrets.json
packages/contracts-bedrock/snapshots/abi/CheckSecrets.json
+102
-0
CheckSecrets.json
...ntracts-bedrock/snapshots/storageLayout/CheckSecrets.json
+9
-0
CheckSecrets.sol
...bedrock/src/periphery/drippie/dripchecks/CheckSecrets.sol
+47
-0
CheckSecrets.t.sol
...rock/test/periphery/drippie/dripchecks/CheckSecrets.t.sol
+183
-0
No files found.
packages/contracts-bedrock/snapshots/abi/CheckSecrets.json
0 → 100644
View file @
38cd9944
[
{
"inputs"
:
[
{
"internalType"
:
"bytes"
,
"name"
:
"_params"
,
"type"
:
"bytes"
}
],
"name"
:
"check"
,
"outputs"
:
[
{
"internalType"
:
"bool"
,
"name"
:
"execute_"
,
"type"
:
"bool"
}
],
"stateMutability"
:
"view"
,
"type"
:
"function"
},
{
"inputs"
:
[
{
"internalType"
:
"bytes"
,
"name"
:
"_secret"
,
"type"
:
"bytes"
}
],
"name"
:
"reveal"
,
"outputs"
:
[],
"stateMutability"
:
"nonpayable"
,
"type"
:
"function"
},
{
"inputs"
:
[
{
"internalType"
:
"bytes32"
,
"name"
:
""
,
"type"
:
"bytes32"
}
],
"name"
:
"revealedSecrets"
,
"outputs"
:
[
{
"internalType"
:
"uint256"
,
"name"
:
""
,
"type"
:
"uint256"
}
],
"stateMutability"
:
"view"
,
"type"
:
"function"
},
{
"anonymous"
:
false
,
"inputs"
:
[
{
"indexed"
:
true
,
"internalType"
:
"bytes32"
,
"name"
:
"secretHash"
,
"type"
:
"bytes32"
},
{
"indexed"
:
false
,
"internalType"
:
"bytes"
,
"name"
:
"secret"
,
"type"
:
"bytes"
}
],
"name"
:
"SecretRevealed"
,
"type"
:
"event"
},
{
"anonymous"
:
false
,
"inputs"
:
[
{
"components"
:
[
{
"internalType"
:
"uint256"
,
"name"
:
"delay"
,
"type"
:
"uint256"
},
{
"internalType"
:
"bytes32"
,
"name"
:
"secretHashMustExist"
,
"type"
:
"bytes32"
},
{
"internalType"
:
"bytes32"
,
"name"
:
"secretHashMustNotExist"
,
"type"
:
"bytes32"
}
],
"indexed"
:
false
,
"internalType"
:
"struct CheckSecrets.Params"
,
"name"
:
"params"
,
"type"
:
"tuple"
}
],
"name"
:
"_EventToExposeStructInABI__Params"
,
"type"
:
"event"
}
]
\ No newline at end of file
packages/contracts-bedrock/snapshots/storageLayout/CheckSecrets.json
0 → 100644
View file @
38cd9944
[
{
"bytes"
:
"32"
,
"label"
:
"revealedSecrets"
,
"offset"
:
0
,
"slot"
:
"0"
,
"type"
:
"mapping(bytes32 => uint256)"
}
]
\ No newline at end of file
packages/contracts-bedrock/src/periphery/drippie/dripchecks/CheckSecrets.sol
0 → 100644
View file @
38cd9944
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;
import { IDripCheck } from "../IDripCheck.sol";
/// @title CheckSecrets
/// @notice DripCheck that checks if specific secrets exist (or not). Supports having a secret that
/// must exist for the check to pass as well as a second secret that must not exist. First
/// secret can be revealed to begin the drip, second secret can be revealed to stop it.
contract CheckSecrets is IDripCheck {
struct Params {
uint256 delay;
bytes32 secretHashMustExist;
bytes32 secretHashMustNotExist;
}
/// @notice External event used to help client-side tooling encode parameters.
/// @param params Parameters to encode.
event _EventToExposeStructInABI__Params(Params params);
/// @notice Event emitted when a secret is revealed.
event SecretRevealed(bytes32 indexed secretHash, bytes secret);
/// @notice Keeps track of when secrets were revealed.
mapping(bytes32 => uint256) public revealedSecrets;
/// @inheritdoc IDripCheck
function check(bytes memory _params) external view returns (bool execute_) {
Params memory params = abi.decode(_params, (Params));
// Check that the secrets have/have not been revealed.
execute_ = (
revealedSecrets[params.secretHashMustExist] > 0
&& block.timestamp >= revealedSecrets[params.secretHashMustExist] + params.delay
&& revealedSecrets[params.secretHashMustNotExist] == 0
);
}
/// @notice Reveal a secret.
/// @param _secret Secret to reveal.
function reveal(bytes memory _secret) external {
bytes32 secretHash = keccak256(_secret);
require(revealedSecrets[secretHash] == 0, "CheckSecrets: secret already revealed");
revealedSecrets[secretHash] = block.timestamp;
emit SecretRevealed(secretHash, _secret);
}
}
packages/contracts-bedrock/test/periphery/drippie/dripchecks/CheckSecrets.t.sol
0 → 100644
View file @
38cd9944
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;
import { Test } from "forge-std/Test.sol";
import { CheckSecrets } from "src/periphery/drippie/dripchecks/CheckSecrets.sol";
/// @title CheckSecretsTest
contract CheckSecretsTest is Test {
/// @notice Event emitted when a secret is revealed.
event SecretRevealed(bytes32 indexed secretHash, bytes secret);
/// @notice An instance of the CheckSecrets contract.
CheckSecrets c;
/// @notice A secret that must exist.
bytes secretMustExist = bytes(string("secretMustExist"));
/// @notice A secret that must not exist.
bytes secretMustNotExist = bytes(string("secretMustNotExist"));
/// @notice A delay period for the check.
uint256 delay = 100;
/// @notice Deploy the `CheckSecrets` contract.
function setUp() external {
c = new CheckSecrets();
}
/// @notice Test that basic secret revealing works.
function test_reveal_succeeds() external {
// Simple reveal and check assertions.
vm.expectEmit(address(c));
emit SecretRevealed(keccak256(secretMustExist), secretMustExist);
c.reveal(secretMustExist);
assertEq(c.revealedSecrets(keccak256(secretMustExist)), block.timestamp);
}
/// @notice Test that revealing the same secret twice does not work.
function test_reveal_twice_fails() external {
// Reveal the secret once.
uint256 ts = block.timestamp;
c.reveal(secretMustExist);
assertEq(c.revealedSecrets(keccak256(secretMustExist)), ts);
// Forward time and reveal again, should fail, same original timestamp.
vm.warp(ts + 1);
vm.expectRevert("CheckSecrets: secret already revealed");
c.reveal(secretMustExist);
assertEq(c.revealedSecrets(keccak256(secretMustExist)), ts);
}
/// @notice Test that the check function returns true when the first secret is revealed but the
/// second secret is still hidden and the delay period has elapsed when the delay
/// period is non-zero. Here we warp to exactly the delay period.
function test_check_secretRevealedWithDelayEq_succeeds() external {
CheckSecrets.Params memory p = CheckSecrets.Params({
delay: delay,
secretHashMustExist: keccak256(secretMustExist),
secretHashMustNotExist: keccak256(secretMustNotExist)
});
// Reveal the secret that must exist.
c.reveal(secretMustExist);
// Forward time to the delay period.
vm.warp(block.timestamp + delay);
// Beyond the delay, secret revealed, check should succeed.
assertEq(c.check(abi.encode(p)), true);
}
/// @notice Test that the check function returns true when the first secret is revealed but the
/// second secret is still hidden and the delay period has elapsed when the delay
/// period is non-zero. Here we warp to after the delay period.
function test_check_secretRevealedWithDelayGt_succeeds() external {
CheckSecrets.Params memory p = CheckSecrets.Params({
delay: delay,
secretHashMustExist: keccak256(secretMustExist),
secretHashMustNotExist: keccak256(secretMustNotExist)
});
// Reveal the secret that must exist.
c.reveal(secretMustExist);
// Forward time to after the delay period.
vm.warp(block.timestamp + delay + 1);
// Beyond the delay, secret revealed, check should succeed.
assertEq(c.check(abi.encode(p)), true);
}
/// @notice Test that the check function returns true when the first secret is revealed but the
/// second secret is still hidden and the delay period is zero, meaning the reveal can
/// happen in the same block as the execution.
function test_check_secretRevealedZeroDelay_succeeds() external {
CheckSecrets.Params memory p = CheckSecrets.Params({
delay: 0,
secretHashMustExist: keccak256(secretMustExist),
secretHashMustNotExist: keccak256(secretMustNotExist)
});
// Reveal the secret that must exist.
c.reveal(secretMustExist);
// Note we don't need to forward time here.
// Secret revealed, no delay, check should succeed.
assertEq(c.check(abi.encode(p)), true);
}
/// @notice Test that the check function returns false when the first secret is revealed but
/// the delay period has not yet elapsed.
function test_check_secretRevealedBeforeDelay_fails() external {
CheckSecrets.Params memory p = CheckSecrets.Params({
delay: delay,
secretHashMustExist: keccak256(secretMustExist),
secretHashMustNotExist: keccak256(secretMustNotExist)
});
// Reveal the secret that must exist.
c.reveal(secretMustExist);
// Forward time to before the delay period.
vm.warp(block.timestamp + delay - 1);
// Not beyond the delay, check should fail.
assertEq(c.check(abi.encode(p)), false);
}
/// @notice Test that the check function returns false when the first secret is not revealed.
function test_check_secretNotRevealed_fails() external {
CheckSecrets.Params memory p = CheckSecrets.Params({
delay: delay,
secretHashMustExist: keccak256(secretMustExist),
secretHashMustNotExist: keccak256(secretMustNotExist)
});
// Forward beyond the delay period.
vm.warp(block.timestamp + delay + 1);
// Secret not revealed, check should fail.
assertEq(c.check(abi.encode(p)), false);
}
/// @notice Test that the check function returns false when the second secret is revealed.
function test_check_secondSecretRevealed_fails() external {
CheckSecrets.Params memory p = CheckSecrets.Params({
delay: delay,
secretHashMustExist: keccak256(secretMustExist),
secretHashMustNotExist: keccak256(secretMustNotExist)
});
// Reveal the secret that must not exist.
c.reveal(secretMustNotExist);
// Forward beyond the delay period.
vm.warp(block.timestamp + delay + 1);
// Both secrets revealed, check should fail.
assertEq(c.check(abi.encode(p)), false);
}
/// @notice Test that the check function returns false when the second secret is revealed even
/// though the first secret is also revealed.
function test_check_firstAndSecondSecretRevealed_fails() external {
CheckSecrets.Params memory p = CheckSecrets.Params({
delay: delay,
secretHashMustExist: keccak256(secretMustExist),
secretHashMustNotExist: keccak256(secretMustNotExist)
});
// Reveal the secret that must exist.
c.reveal(secretMustExist);
// Reveal the secret that must not exist.
c.reveal(secretMustNotExist);
// Forward beyond the delay period.
vm.warp(block.timestamp + delay + 1);
// Both secrets revealed, check should fail.
assertEq(c.check(abi.encode(p)), false);
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment