Skip to content

Commit

Permalink
feat: add ERC5564Announcer contract and tests (#2)
Browse files Browse the repository at this point in the history
See [ERC-5564](https://eips.ethereum.org/EIPS/eip-5564) for the spec. The contract is super simple so we really only have one test, if you have ideas for more tests let me know.

This PR also turns off the metadata hash, that way the resulting bytecode is independent of the machine it's compiled on.
  • Loading branch information
mds1 authored Jul 20, 2023
1 parent c250d6d commit b8222da
Show file tree
Hide file tree
Showing 8 changed files with 117 additions and 46 deletions.
1 change: 1 addition & 0 deletions foundry.toml
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
[profile.default]
bytecode_hash = "none"
evm_version = "paris"
optimizer = true
optimizer_runs = 10_000_000
Expand Down
10 changes: 5 additions & 5 deletions script/Deploy.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@

pragma solidity 0.8.20;

import "forge-std/Script.sol";
import {Counter} from "src/Counter.sol";
import {Script} from "forge-std/Script.sol";
import {ERC5564Announcer} from "src/ERC5564Announcer.sol";

contract Deploy is Script {
Counter counter;
ERC5564Announcer announcer;

function run() public {
vm.startBroadcast();
counter = new Counter();
vm.broadcast();
announcer = new ERC5564Announcer();
}
}
14 changes: 0 additions & 14 deletions src/Counter.sol

This file was deleted.

19 changes: 19 additions & 0 deletions src/ERC5564Announcer.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.20;

import {IERC5564Announcer} from "./interfaces/IERC5564Announcer.sol";

/// @dev `ERC5564Announcer` contract to emit an `Announcement` event to broadcast information about
/// a transaction involving a stealth address. See
/// [ERC-5564](https://eips.ethereum.org/EIPS/eip-5564) to learn more.
contract ERC5564Announcer is IERC5564Announcer {
/// @inheritdoc IERC5564Announcer
function announce(
uint256 schemeId,
address stealthAddress,
bytes memory ephemeralPubKey,
bytes memory metadata
) external {
emit Announcement(schemeId, stealthAddress, msg.sender, ephemeralPubKey, metadata);
}
}
40 changes: 40 additions & 0 deletions src/interfaces/IERC5564Announcer.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;

/// @dev Interface for calling the `ERC5564Announcer` contract, which emits an `Announcement` event
/// to broadcast information about a transaction involving a stealth address. See
/// [ERC-5564](https://eips.ethereum.org/EIPS/eip-5564) to learn more.
interface IERC5564Announcer {
/// @dev Emitted when something is sent to a stealth address.
/// @param schemeId Identifier corresponding to the applied stealth address scheme, e.g. 0 for
/// secp256k1, as specified in ERC-5564.
/// @param stealthAddress The computed stealth address for the recipient.
/// @param caller The caller of the `announce` function that emitted this event.
/// @param ephemeralPubKey Ephemeral public key used by the sender to derive the `stealthAddress`.
/// @param metadata Arbitrary data to emit with the event. The first byte MUST be the view tag.
/// The remaining metadata can be used by the senders however they like. See
/// [ERC-5564](https://eips.ethereum.org/EIPS/eip-5564) for recommendations on how to structure
/// this metadata.
event Announcement(
uint256 indexed schemeId,
address indexed stealthAddress,
address indexed caller,
bytes ephemeralPubKey,
bytes metadata
);

/// @dev Called by integrators to emit an `Announcement` event.
/// @param schemeId The applied stealth address scheme (such as secp25k1).
/// @param stealthAddress The computed stealth address for the recipient.
/// @param ephemeralPubKey Ephemeral public key used by the sender.
/// @param metadata Arbitrary data to emit with the event. The first byte MUST be the view tag.
/// The remaining metadata can be used by the senders however they like. See
/// [ERC-5564](https://eips.ethereum.org/EIPS/eip-5564) for recommendations on how to structure
/// this metadata.
function announce(
uint256 schemeId,
address stealthAddress,
bytes memory ephemeralPubKey,
bytes memory metadata
) external;
}
26 changes: 0 additions & 26 deletions test/Counter.t.sol

This file was deleted.

51 changes: 51 additions & 0 deletions test/ERC5564Announcer.t.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.20;

import {Test} from "forge-std/Test.sol";
import {Deploy} from "script/Deploy.s.sol";

contract ERC5564AnnouncerTest is Test, Deploy {
event Announcement(
uint256 indexed schemeId,
address indexed stealthAddress,
address indexed caller,
bytes ephemeralPubKey,
bytes metadata
);

function setUp() public {
Deploy.run();
}
}

contract Announce is ERC5564AnnouncerTest {
function testFuzz_EmitsAnnouncementEvent(
uint256 schemeId,
address stealthAddress,
address caller,
bytes memory ephemeralPubKey,
bytes memory metadata
) external {
vm.prank(caller);
vm.expectEmit();
emit Announcement(schemeId, stealthAddress, caller, ephemeralPubKey, metadata);
announcer.announce(schemeId, stealthAddress, ephemeralPubKey, metadata);
}

// This test is a subset of `testFuzz_EmitsAnnouncementEvent`, and is mainly present to make
// the `announce` method's specification more explicit. For this reason, we set the number of runs
// to 1 for all profiles.
/// forge-config: default.fuzz.runs = 1
/// forge-config: ci.fuzz.runs = 1
/// forge-config: lite.fuzz.runs = 1
function testFuzz_NeverReverts(
uint256 schemeId,
address stealthAddress,
address caller,
bytes memory ephemeralPubKey,
bytes memory metadata
) external {
vm.prank(caller);
announcer.announce(schemeId, stealthAddress, ephemeralPubKey, metadata);
}
}

0 comments on commit b8222da

Please sign in to comment.