Skip to content

Instantly share code, notes, and snippets.

@p14041999
Created August 23, 2024 08:18
Show Gist options
  • Select an option

  • Save p14041999/7e2705b5ff83ff56f37bda490600182d to your computer and use it in GitHub Desktop.

Select an option

Save p14041999/7e2705b5ff83ff56f37bda490600182d to your computer and use it in GitHub Desktop.
Created using remix-ide: Realtime Ethereum Contract Compiler and Runtime. Load this file by pasting this gists URL or ID at https://remix.ethereum.org/#version=soljson-v0.8.26+commit.8a97fa7a.js&optimize=false&runs=200&gist=
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
/**
DEAR Airdrop Claim
Call claim function with generated Signature
*/
interface IERC20{
function allowance(address owner, address spender) external view returns (uint256);
function transferFrom(address from, address to, uint256 amount) external returns (bool);
}
contract VerifySignature {
address signer = address(0);
IERC20 token = IERC20(address(0));
event AirdropDistributed(address indexed to, uint256 amount);
mapping(address=>bool) public isClaimed;
constructor(address signer_,address token_){
signer = signer_;
token = IERC20(token_);
}
function getMessageHash(
address _to,
uint256 _amount,
string memory _message,
uint256 _nonce
) internal pure returns (bytes32) {
return keccak256(abi.encodePacked(_to, _amount, _message, _nonce));
}
function getEthSignedMessageHash(bytes32 _messageHash)
internal
pure
returns (bytes32)
{
return keccak256(
abi.encodePacked("\x19Ethereum Signed Message:\n32", _messageHash)
);
}
function verify(
address _signer,
address _to,
uint256 _amount,
string memory _message,
uint256 _nonce,
bytes memory signature
) public pure returns (bool) {
bytes32 messageHash = getMessageHash(_to, _amount, _message, _nonce);
bytes32 ethSignedMessageHash = getEthSignedMessageHash(messageHash);
return recoverSigner(ethSignedMessageHash, signature) == _signer;
}
function claim(
address to,
uint256 nonce,
bytes memory signature
) public {
// Data
uint256 amount = 1000 * 10**18;
// Check Validity
require(!isClaimed[to],"already claimed");
require(verify(signer,to,amount,"Winner of airdrop",nonce,signature),"invalid claim");
require(token.allowance(signer,address(this)) >= amount,"increase allowance");
// Distribute
isClaimed[to] = true;
token.transferFrom(signer,to,amount);
// EMIT event
emit AirdropDistributed(to,amount);
}
function recoverSigner(
bytes32 _ethSignedMessageHash,
bytes memory _signature
) internal pure returns (address) {
(bytes32 r, bytes32 s, uint8 v) = splitSignature(_signature);
return ecrecover(_ethSignedMessageHash, v, r, s);
}
function splitSignature(bytes memory sig)
internal
pure
returns (bytes32 r, bytes32 s, uint8 v)
{
require(sig.length == 65, "invalid signature length");
assembly {
r := mload(add(sig, 32))
s := mload(add(sig, 64))
v := byte(0, mload(add(sig, 96)))
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment