Skip to content

Commit

Permalink
Merge branch 'main' into verify_full_merkle
Browse files Browse the repository at this point in the history
  • Loading branch information
dantaik authored Feb 11, 2024
2 parents 8e1b3b2 + 603f24b commit e7a8c78
Show file tree
Hide file tree
Showing 20 changed files with 607 additions and 420 deletions.
1 change: 1 addition & 0 deletions packages/protocol/contracts/L1/TaikoData.sol
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ library TaikoData {
bytes32 blockHash;
bytes32 stateRoot;
bytes32 graffiti;
bytes32[2] __reserved;
}

/// @dev Struct representing state transition data.
Expand Down
9 changes: 1 addition & 8 deletions packages/protocol/contracts/signal/SignalService.sol
Original file line number Diff line number Diff line change
Expand Up @@ -129,8 +129,7 @@ contract SignalService is EssentialContract, ISignalService {
// If a signal is sent from chainA -> chainB -> chainC (this chain), we verify the proofs in
// the following order:
// 1. using chainC's latest parent's stateRoot to verify that chainB's TaikoL1/TaikoL2
// contract has
// sent a given hop stateRoot on chainB using its own signal service.
// contract has sent a given hop stateRoot on chainB using its own signal service.
// 2. using the verified hop stateRoot to verify that the source app on chainA has sent a
// signal using its own signal service.
// We always verify the proofs in the reversed order (top to bottom).
Expand Down Expand Up @@ -200,12 +199,6 @@ contract SignalService is EssentialContract, ISignalService {
return keccak256(abi.encodePacked("SIGNAL", chainId, app, signal));
}

/// @notice Tells if we need to check real proof or it is a test.
/// @return Returns true to skip checking inclusion proofs.
function skipProofCheck() public pure virtual returns (bool) {
return false;
}

function _authorizePause(address) internal pure override {
revert SS_UNSUPPORTED();
}
Expand Down
30 changes: 25 additions & 5 deletions packages/protocol/contracts/team/airdrop/ERC20Airdrop.sol
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
pragma solidity 0.8.24;

import "lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol";
import "lib/openzeppelin-contracts/contracts/governance/utils/IVotes.sol";
import "./MerkleClaimable.sol";

/// @title ERC20Airdrop
Expand All @@ -25,8 +26,8 @@ contract ERC20Airdrop is MerkleClaimable {
uint256[48] private __gap;

function init(
uint64 _claimStarts,
uint64 _claimEnds,
uint64 _claimStart,
uint64 _claimEnd,
bytes32 _merkleRoot,
address _token,
address _vault
Expand All @@ -35,14 +36,33 @@ contract ERC20Airdrop is MerkleClaimable {
initializer
{
__Essential_init();
_setConfig(_claimStarts, _claimEnds, _merkleRoot);
__MerkleClaimable_init(_claimStart, _claimEnd, _merkleRoot);

token = _token;
vault = _vault;
}

function _claimWithData(bytes calldata data) internal override {
(address user, uint256 amount) = abi.decode(data, (address, uint256));
function claimAndDelegate(
address user,
uint256 amount,
bytes32[] calldata proof,
bytes calldata delegationData
)
external
nonReentrant
{
// Check if this can be claimed
_verifyClaim(abi.encode(user, amount), proof);

// Transfer the tokens
IERC20(token).transferFrom(vault, user, amount);

// Delegate the voting power to delegatee.
// Note that the signature (v,r,s) may not correspond to the user address,
// but since the data is provided by Taiko backend, it's not an issue even if
// client can change the data to call delegateBySig for another user.
(address delegatee, uint256 nonce, uint256 expiry, uint8 v, bytes32 r, bytes32 s) =
abi.decode(delegationData, (address, uint256, uint256, uint8, bytes32, bytes32));
IVotes(token).delegateBySig(delegatee, nonce, expiry, v, r, s);
}
}
20 changes: 11 additions & 9 deletions packages/protocol/contracts/team/airdrop/ERC20Airdrop2.sol
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ contract ERC20Airdrop2 is MerkleClaimable {
}

function init(
uint64 _claimStarts,
uint64 _claimEnds,
uint64 _claimStart,
uint64 _claimEnd,
bytes32 _merkleRoot,
address _token,
address _vault,
Expand All @@ -58,14 +58,21 @@ contract ERC20Airdrop2 is MerkleClaimable {
initializer
{
__Essential_init();
// Unix timestamp=_claimEnds+1 marks the first timestamp the users are able to withdraw.
_setConfig(_claimStarts, _claimEnds, _merkleRoot);
__MerkleClaimable_init(_claimStart, _claimEnd, _merkleRoot);

token = _token;
vault = _vault;
withdrawalWindow = _withdrawalWindow;
}

function claim(address user, uint256 amount, bytes32[] calldata proof) external nonReentrant {
// Check if this can be claimed
_verifyClaim(abi.encode(user, amount), proof);

// Assign the tokens
claimedAmount[user] += amount;
}

/// @notice External withdraw function
/// @param user User address
function withdraw(address user) external ongoingWithdrawals {
Expand Down Expand Up @@ -102,9 +109,4 @@ contract ERC20Airdrop2 is MerkleClaimable {

withdrawableAmount = timeBasedAllowance - withdrawnAmount[user];
}

function _claimWithData(bytes calldata data) internal override {
(address user, uint256 amount) = abi.decode(data, (address, uint256));
claimedAmount[user] += amount;
}
}
19 changes: 14 additions & 5 deletions packages/protocol/contracts/team/airdrop/ERC721Airdrop.sol
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ contract ERC721Airdrop is MerkleClaimable {
uint256[48] private __gap;

function init(
uint64 _claimStarts,
uint64 _claimEnds,
uint64 _claimStart,
uint64 _claimEnd,
bytes32 _merkleRoot,
address _token,
address _vault
Expand All @@ -34,15 +34,24 @@ contract ERC721Airdrop is MerkleClaimable {
initializer
{
__Essential_init();
_setConfig(_claimStarts, _claimEnds, _merkleRoot);
__MerkleClaimable_init(_claimStart, _claimEnd, _merkleRoot);

token = _token;
vault = _vault;
}

function _claimWithData(bytes calldata data) internal override {
(address user, uint256[] memory tokenIds) = abi.decode(data, (address, uint256[]));
function claim(
address user,
uint256[] calldata tokenIds,
bytes32[] calldata proof
)
external
nonReentrant
{
// Check if this can be claimed
_verifyClaim(abi.encode(user, tokenIds), proof);

// Transfer the tokens
for (uint256 i; i < tokenIds.length; ++i) {
IERC721Upgradeable(token).safeTransferFrom(vault, user, tokenIds[i]);
}
Expand Down
63 changes: 36 additions & 27 deletions packages/protocol/contracts/team/airdrop/MerkleClaimable.sol
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,7 @@

pragma solidity 0.8.24;

import { MerkleProofUpgradeable } from
"lib/openzeppelin-contracts-upgradeable/contracts/utils/cryptography/MerkleProofUpgradeable.sol";
import "lib/openzeppelin-contracts/contracts/utils/cryptography/MerkleProof.sol";
import "../../common/EssentialContract.sol";

/// @title MerkleClaimable
Expand All @@ -42,27 +41,6 @@ abstract contract MerkleClaimable is EssentialContract {
_;
}

function claim(
bytes calldata data,
bytes32[] calldata proof
)
external
nonReentrant
ongoingClaim
{
bytes32 hash = keccak256(abi.encode("CLAIM_TAIKO_AIRDROP", data));

if (isClaimed[hash]) revert CLAIMED_ALREADY();

if (!MerkleProofUpgradeable.verify(proof, merkleRoot, hash)) {
revert INVALID_PROOF();
}

isClaimed[hash] = true;
_claimWithData(data);
emit Claimed(hash);
}

/// @notice Set config parameters
/// @param _claimStart Unix timestamp for claim start
/// @param _claimEnd Unix timestamp for claim end
Expand All @@ -78,12 +56,43 @@ abstract contract MerkleClaimable is EssentialContract {
_setConfig(_claimStart, _claimEnd, _merkleRoot);
}

function _setConfig(uint64 _claimStart, uint64 _claimEnd, bytes32 _merkleRoot) internal {
// solhint-disable-next-line func-name-mixedcase
function __MerkleClaimable_init(
uint64 _claimStart,
uint64 _claimEnd,
bytes32 _merkleRoot
)
internal
{
_setConfig(_claimStart, _claimEnd, _merkleRoot);
}

function _verifyClaim(bytes memory data, bytes32[] calldata proof) internal ongoingClaim {
bytes32 hash = keccak256(abi.encode("CLAIM_TAIKO_AIRDROP", data));

if (isClaimed[hash]) revert CLAIMED_ALREADY();
if (!_verifyMerkleProof(proof, merkleRoot, hash)) revert INVALID_PROOF();

isClaimed[hash] = true;
emit Claimed(hash);
}

function _verifyMerkleProof(
bytes32[] calldata _proof,
bytes32 _merkleRoot,
bytes32 _value
)
internal
pure
virtual
returns (bool)
{
return MerkleProof.verify(_proof, _merkleRoot, _value);
}

function _setConfig(uint64 _claimStart, uint64 _claimEnd, bytes32 _merkleRoot) private {
claimStart = _claimStart;
claimEnd = _claimEnd;
merkleRoot = _merkleRoot;
}

/// @dev Must revert in case of errors.
function _claimWithData(bytes calldata data) internal virtual;
}
3 changes: 3 additions & 0 deletions packages/protocol/contracts/tokenvault/BaseNFTVault.sol
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ abstract contract BaseNFTVault is BaseVault {
address indexed from,
address indexed to,
uint64 destChainId,
address ctoken,
address token,
uint256[] tokenIds,
uint256[] amounts
Expand All @@ -87,6 +88,7 @@ abstract contract BaseNFTVault is BaseVault {
event TokenReleased(
bytes32 indexed msgHash,
address indexed from,
address ctoken,
address token,
uint256[] tokenIds,
uint256[] amounts
Expand All @@ -97,6 +99,7 @@ abstract contract BaseNFTVault is BaseVault {
address indexed from,
address indexed to,
uint64 srcChainId,
address ctoken,
address token,
uint256[] tokenIds,
uint256[] amounts
Expand Down
9 changes: 5 additions & 4 deletions packages/protocol/contracts/tokenvault/BridgedERC20.sol
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,10 @@ contract BridgedERC20 is
error BTOKEN_INVALID_PARAMS();
error BTOKEN_UNAUTHORIZED();


modifier onlyOwnerOrSnapshooter {
if (msg.sender != owner() && msg.sender != snapshooter)
revert BTOKEN_UNAUTHORIZED();
modifier onlyOwnerOrSnapshooter() {
if (msg.sender != owner() && msg.sender != snapshooter) {
revert BTOKEN_UNAUTHORIZED();
}
_;
}
/// @notice Initializes the contract.
Expand All @@ -59,6 +59,7 @@ contract BridgedERC20 is
/// @param _decimals The number of decimal places of the source token.
/// @param _symbol The symbol of the token.
/// @param _name The name of the token.

function init(
address _addressManager,
address _srcToken,
Expand Down
Loading

0 comments on commit e7a8c78

Please sign in to comment.