ERC1363 support
This commit is contained in:
parent
e77f44b3c1
commit
77a0cf4461
|
@ -8,11 +8,15 @@ import "@openzeppelin/contracts/access/Ownable.sol";
|
|||
import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Permit.sol";
|
||||
import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Votes.sol";
|
||||
import "@openzeppelin/contracts/token/ERC20/extensions/ERC20FlashMint.sol";
|
||||
import {Address} from "@openzeppelin/contracts/utils/Address.sol";
|
||||
import "erc-payable-token/contracts/token/ERC1363/IERC1363.sol";
|
||||
import "erc-payable-token/contracts/token/ERC1363/IERC1363Spender.sol";
|
||||
import "erc-payable-token/contracts/token/ERC1363/IERC1363Receiver.sol";
|
||||
|
||||
abstract contract AbstractGrans is ERC20, ERC20Burnable, Pausable, Ownable, ERC20Permit, ERC20Votes, ERC20FlashMint {
|
||||
constructor() ERC20("10Grans", "GRANS") ERC20Permit("10Grans") {
|
||||
abstract contract AbstractGrans is IERC1363, ERC20, ERC20Burnable, Pausable, Ownable, ERC20Permit, ERC20Votes, ERC20FlashMint {
|
||||
using Address for address;
|
||||
|
||||
}
|
||||
constructor() ERC20("10Grans", "GRANS") ERC20Permit("10Grans") {}
|
||||
|
||||
function pause() public onlyOwner {
|
||||
_pause();
|
||||
|
@ -22,6 +26,14 @@ abstract contract AbstractGrans is ERC20, ERC20Burnable, Pausable, Ownable, ERC2
|
|||
_unpause();
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev See {IERC165-supportsInterface}.
|
||||
*/
|
||||
function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165) returns (bool) {
|
||||
return interfaceId == type(IERC1363).interfaceId;
|
||||
}
|
||||
|
||||
|
||||
function _beforeTokenTransfer(address from, address to, uint256 amount) internal override whenNotPaused {
|
||||
super._beforeTokenTransfer(from, to, amount);
|
||||
}
|
||||
|
@ -40,11 +52,151 @@ abstract contract AbstractGrans is ERC20, ERC20Burnable, Pausable, Ownable, ERC2
|
|||
super._burn(account, amount);
|
||||
}
|
||||
|
||||
function balanceOf(address account) public view virtual override(ERC20) returns (uint256) {
|
||||
function balanceOf(address account) public view virtual override(ERC20, IERC20) returns (uint256) {
|
||||
return ERC20.balanceOf(account);
|
||||
}
|
||||
|
||||
function transferFrom(address sender, address recipient, uint256 amount) public virtual override(ERC20) returns (bool) {
|
||||
function transferFrom(address sender, address recipient, uint256 amount) public virtual override(ERC20, IERC20) returns (bool) {
|
||||
return ERC20.transferFrom(sender, recipient, amount);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Transfer tokens to a specified address and then execute a callback on `to`.
|
||||
* @param to The address to transfer to.
|
||||
* @param amount The amount to be transferred.
|
||||
* @return A boolean that indicates if the operation was successful.
|
||||
*/
|
||||
function transferAndCall(address to, uint256 amount) public virtual override returns (bool) {
|
||||
return transferAndCall(to, amount, "");
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Transfer tokens to a specified address and then execute a callback on `to`.
|
||||
* @param to The address to transfer to
|
||||
* @param amount The amount to be transferred
|
||||
* @param data Additional data with no specified format
|
||||
* @return A boolean that indicates if the operation was successful.
|
||||
*/
|
||||
function transferAndCall(address to, uint256 amount, bytes memory data) public virtual override returns (bool) {
|
||||
transfer(to, amount);
|
||||
require(_checkOnTransferReceived(_msgSender(), to, amount, data), "ERC1363: receiver returned wrong data");
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Transfer tokens from one address to another and then execute a callback on `to`.
|
||||
* @param from The address which you want to send tokens from
|
||||
* @param to The address which you want to transfer to
|
||||
* @param amount The amount of tokens to be transferred
|
||||
* @return A boolean that indicates if the operation was successful.
|
||||
*/
|
||||
function transferFromAndCall(address from, address to, uint256 amount) public virtual override returns (bool) {
|
||||
return transferFromAndCall(from, to, amount, "");
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Transfer tokens from one address to another and then execute a callback on `to`.
|
||||
* @param from The address which you want to send tokens from
|
||||
* @param to The address which you want to transfer to
|
||||
* @param amount The amount of tokens to be transferred
|
||||
* @param data Additional data with no specified format
|
||||
* @return A boolean that indicates if the operation was successful.
|
||||
*/
|
||||
function transferFromAndCall(
|
||||
address from,
|
||||
address to,
|
||||
uint256 amount,
|
||||
bytes memory data
|
||||
) public virtual override returns (bool) {
|
||||
transferFrom(from, to, amount);
|
||||
require(_checkOnTransferReceived(from, to, amount, data), "ERC1363: receiver returned wrong data");
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Approve spender to transfer tokens and then execute a callback on `spender`.
|
||||
* @param spender The address allowed to transfer to
|
||||
* @param amount The amount allowed to be transferred
|
||||
* @return A boolean that indicates if the operation was successful.
|
||||
*/
|
||||
function approveAndCall(address spender, uint256 amount) public virtual override returns (bool) {
|
||||
return approveAndCall(spender, amount, "");
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Approve spender to transfer tokens and then execute a callback on `spender`.
|
||||
* @param spender The address allowed to transfer to.
|
||||
* @param amount The amount allowed to be transferred.
|
||||
* @param data Additional data with no specified format.
|
||||
* @return A boolean that indicates if the operation was successful.
|
||||
*/
|
||||
function approveAndCall(address spender, uint256 amount, bytes memory data) public virtual override returns (bool) {
|
||||
approve(spender, amount);
|
||||
require(_checkOnApprovalReceived(spender, amount, data), "ERC1363: spender returned wrong data");
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Internal function to invoke {IERC1363Receiver-onTransferReceived} on a target address.
|
||||
* The call is not executed if the target address is not a contract.
|
||||
* @param sender address Representing the previous owner of the given token amount
|
||||
* @param recipient address Target address that will receive the tokens
|
||||
* @param amount uint256 The amount mount of tokens to be transferred
|
||||
* @param data bytes Optional data to send along with the call
|
||||
* @return whether the call correctly returned the expected magic value
|
||||
*/
|
||||
function _checkOnTransferReceived(
|
||||
address sender,
|
||||
address recipient,
|
||||
uint256 amount,
|
||||
bytes memory data
|
||||
) internal virtual returns (bool) {
|
||||
if (!recipient.isContract()) {
|
||||
revert("ERC1363: transfer to non contract address");
|
||||
}
|
||||
|
||||
try IERC1363Receiver(recipient).onTransferReceived(_msgSender(), sender, amount, data) returns (bytes4 retval) {
|
||||
return retval == IERC1363Receiver.onTransferReceived.selector;
|
||||
} catch (bytes memory reason) {
|
||||
if (reason.length == 0) {
|
||||
revert("ERC1363: transfer to non ERC1363Receiver implementer");
|
||||
} else {
|
||||
/// @solidity memory-safe-assembly
|
||||
assembly {
|
||||
revert(add(32, reason), mload(reason))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Internal function to invoke {IERC1363Receiver-onApprovalReceived} on a target address.
|
||||
* The call is not executed if the target address is not a contract.
|
||||
* @param spender address The address which will spend the funds
|
||||
* @param amount uint256 The amount of tokens to be spent
|
||||
* @param data bytes Optional data to send along with the call
|
||||
* @return whether the call correctly returned the expected magic value
|
||||
*/
|
||||
function _checkOnApprovalReceived(
|
||||
address spender,
|
||||
uint256 amount,
|
||||
bytes memory data
|
||||
) internal virtual returns (bool) {
|
||||
if (!spender.isContract()) {
|
||||
revert("ERC1363: approve a non contract address");
|
||||
}
|
||||
|
||||
try IERC1363Spender(spender).onApprovalReceived(_msgSender(), amount, data) returns (bytes4 retval) {
|
||||
return retval == IERC1363Spender.onApprovalReceived.selector;
|
||||
} catch (bytes memory reason) {
|
||||
if (reason.length == 0) {
|
||||
revert("ERC1363: approve a non ERC1363Spender implementer");
|
||||
} else {
|
||||
/// @solidity memory-safe-assembly
|
||||
assembly {
|
||||
revert(add(32, reason), mload(reason))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,17 @@
|
|||
import { HardhatUserConfig } from "hardhat/config";
|
||||
import "@nomicfoundation/hardhat-toolbox";
|
||||
import "hardhat-contract-sizer";
|
||||
|
||||
const config: HardhatUserConfig = {
|
||||
solidity: "0.8.19",
|
||||
solidity: {
|
||||
version: "0.8.19",
|
||||
settings: {
|
||||
optimizer: {
|
||||
enabled: true,
|
||||
runs: 200
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export default config;
|
||||
|
|
|
@ -7,14 +7,16 @@
|
|||
"": {
|
||||
"name": "10grans-ng",
|
||||
"version": "1.0.0",
|
||||
"license": "ISC",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@arbitrum/token-bridge-contracts": "^1.0.0-beta.0",
|
||||
"@openzeppelin/contracts": "^4.9.3"
|
||||
"@openzeppelin/contracts": "^4.9.3",
|
||||
"erc-payable-token": "^4.9.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@nomicfoundation/hardhat-toolbox": "^3.0.0",
|
||||
"hardhat": "^2.17.1",
|
||||
"hardhat-contract-sizer": "^2.10.0",
|
||||
"prettier": "^3.0.1",
|
||||
"prettier-plugin-solidity": "^1.1.3"
|
||||
}
|
||||
|
@ -100,6 +102,16 @@
|
|||
"case": "^1.6.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@colors/colors": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz",
|
||||
"integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"engines": {
|
||||
"node": ">=0.1.90"
|
||||
}
|
||||
},
|
||||
"node_modules/@cspotcode/source-map-support": {
|
||||
"version": "0.8.1",
|
||||
"resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz",
|
||||
|
@ -4150,6 +4162,14 @@
|
|||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/erc-payable-token": {
|
||||
"version": "4.9.3",
|
||||
"resolved": "https://registry.npmjs.org/erc-payable-token/-/erc-payable-token-4.9.3.tgz",
|
||||
"integrity": "sha512-hAkSyH+TfXvbTyrlcOpGhzQkSTgrRWkAktOhRUL2vY2sztYr3twjxhPydaK6CI4uf9+nk6SpujiRrPqxoDOd/w==",
|
||||
"dependencies": {
|
||||
"@openzeppelin/contracts": "4.9.3"
|
||||
}
|
||||
},
|
||||
"node_modules/es-abstract": {
|
||||
"version": "1.22.1",
|
||||
"resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.1.tgz",
|
||||
|
@ -5814,6 +5834,105 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"node_modules/hardhat-contract-sizer": {
|
||||
"version": "2.10.0",
|
||||
"resolved": "https://registry.npmjs.org/hardhat-contract-sizer/-/hardhat-contract-sizer-2.10.0.tgz",
|
||||
"integrity": "sha512-QiinUgBD5MqJZJh1hl1jc9dNnpJg7eE/w4/4GEnrcmZJJTDbVFNe3+/3Ep24XqISSkYxRz36czcPHKHd/a0dwA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"chalk": "^4.0.0",
|
||||
"cli-table3": "^0.6.0",
|
||||
"strip-ansi": "^6.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"hardhat": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/hardhat-contract-sizer/node_modules/ansi-styles": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
|
||||
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"color-convert": "^2.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/hardhat-contract-sizer/node_modules/chalk": {
|
||||
"version": "4.1.2",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
|
||||
"integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"ansi-styles": "^4.1.0",
|
||||
"supports-color": "^7.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/chalk/chalk?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/hardhat-contract-sizer/node_modules/cli-table3": {
|
||||
"version": "0.6.3",
|
||||
"resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.3.tgz",
|
||||
"integrity": "sha512-w5Jac5SykAeZJKntOxJCrm63Eg5/4dhMWIcuTbo9rpE+brgaSZo0RuNJZeOyMgsUdhDeojvgyQLmjI+K50ZGyg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"string-width": "^4.2.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "10.* || >= 12.*"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@colors/colors": "1.5.0"
|
||||
}
|
||||
},
|
||||
"node_modules/hardhat-contract-sizer/node_modules/color-convert": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
||||
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"color-name": "~1.1.4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=7.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/hardhat-contract-sizer/node_modules/color-name": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
|
||||
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/hardhat-contract-sizer/node_modules/has-flag": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
|
||||
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/hardhat-contract-sizer/node_modules/supports-color": {
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
|
||||
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"has-flag": "^4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/hardhat-gas-reporter": {
|
||||
"version": "1.0.9",
|
||||
"resolved": "https://registry.npmjs.org/hardhat-gas-reporter/-/hardhat-gas-reporter-1.0.9.tgz",
|
||||
|
|
|
@ -21,11 +21,13 @@
|
|||
"devDependencies": {
|
||||
"@nomicfoundation/hardhat-toolbox": "^3.0.0",
|
||||
"hardhat": "^2.17.1",
|
||||
"hardhat-contract-sizer": "^2.10.0",
|
||||
"prettier": "^3.0.1",
|
||||
"prettier-plugin-solidity": "^1.1.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"@arbitrum/token-bridge-contracts": "^1.0.0-beta.0",
|
||||
"@openzeppelin/contracts": "^4.9.3"
|
||||
"@openzeppelin/contracts": "^4.9.3",
|
||||
"erc-payable-token": "^4.9.3"
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue