Created
August 23, 2024 08:18
-
-
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=
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // 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