WIP: use openzeppelin contracts

This commit is contained in:
hueso 2025-08-02 20:03:46 -03:00
parent e57428525b
commit 407ea51d6a
10 changed files with 18 additions and 350 deletions

View File

@ -4,8 +4,9 @@ pragma solidity ^0.8.19;
import { ERC20, OwnerSettings } from "contracts/core/OwnerSettings.sol";
import { ECDSA } from "contracts/lib/utils/ECDSA.sol";
import { MerkleProofLib as Merkle } from "contracts/lib/utils/MerkleProofLib.sol";
import { ReentrancyGuard } from "contracts/lib/utils/ReentrancyGuard.sol";
import { MessageHashUtils } from "@openzeppelin/contracts/utils/cryptography/MessageHashUtils.sol";
import { MerkleProof as Merkle } from "@openzeppelin/contracts/utils/cryptography/MerkleProof.sol";
import { ReentrancyGuard } from "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
abstract contract BaseUtils is
OwnerSettings,
@ -44,7 +45,7 @@ abstract contract BaseUtils is
!validBacenSigners(
_castAddrToKey(
ECDSA.recoverCalldata(
ECDSA.toEthSignedMessageHash(
MessageHashUtils.toEthSignedMessageHash(
_message
),
_signature

View File

@ -1,7 +1,7 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;
import { ERC20 } from "contracts/lib/tokens/ERC20.sol";
import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
library DataTypes {

View File

@ -1,7 +1,7 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;
import { ERC20 } from "contracts/lib/tokens/ERC20.sol";
import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
// prettier-ignore
interface EventAndErrors {

View File

@ -1,10 +1,10 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;
import { ERC20 } from "../tokens/ERC20.sol";
import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
contract MockToken is ERC20 {
constructor(uint256 supply) ERC20("MockBRL", "MBRL", 18) {
constructor(uint256 supply) ERC20("MockBRL", "MBRL") {
_mint(msg.sender, supply);
}

View File

@ -1,250 +0,0 @@
// SPDX-License-Identifier: MIT
pragma solidity >=0.8.4;
/// @notice Modern and gas efficient ERC20 + EIP-2612 implementation.
/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC20.sol)
/// @author Modified from Uniswap (https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/UniswapV2ERC20.sol)
/// @dev Do not manually set balances without updating totalSupply, as the sum of all user balances must not exceed it.
abstract contract ERC20 {
/*//////////////////////////////////////////////////////////////
EVENTS
//////////////////////////////////////////////////////////////*/
event Transfer(
address indexed from,
address indexed to,
uint256 amount
);
event Approval(
address indexed owner,
address indexed spender,
uint256 amount
);
/*//////////////////////////////////////////////////////////////
METADATA STORAGE
//////////////////////////////////////////////////////////////*/
string public name;
string public symbol;
uint8 public immutable decimals;
/*//////////////////////////////////////////////////////////////
ERC20 STORAGE
//////////////////////////////////////////////////////////////*/
uint256 public totalSupply;
mapping(address => uint256) public balanceOf;
mapping(address => mapping(address => uint256))
public allowance;
/*//////////////////////////////////////////////////////////////
EIP-2612 STORAGE
//////////////////////////////////////////////////////////////*/
uint256 internal immutable INITIAL_CHAIN_ID;
bytes32 internal immutable INITIAL_DOMAIN_SEPARATOR;
mapping(address => uint256) public nonces;
/*//////////////////////////////////////////////////////////////
CONSTRUCTOR
//////////////////////////////////////////////////////////////*/
constructor(
string memory _name,
string memory _symbol,
uint8 _decimals
) {
name = _name;
symbol = _symbol;
decimals = _decimals;
INITIAL_CHAIN_ID = block.chainid;
INITIAL_DOMAIN_SEPARATOR = computeDomainSeparator();
}
/*//////////////////////////////////////////////////////////////
ERC20 LOGIC
//////////////////////////////////////////////////////////////*/
function approve(
address spender,
uint256 amount
) public virtual returns (bool) {
allowance[msg.sender][spender] = amount;
emit Approval(msg.sender, spender, amount);
return true;
}
function transfer(
address to,
uint256 amount
) public virtual returns (bool) {
balanceOf[msg.sender] -= amount;
// Cannot overflow because the sum of all user
// balances can't exceed the max uint256 value.
unchecked {
balanceOf[to] += amount;
}
emit Transfer(msg.sender, to, amount);
return true;
}
function transferFrom(
address from,
address to,
uint256 amount
) public virtual returns (bool) {
uint256 allowed = allowance[from][msg.sender]; // Saves gas for limited approvals.
if (allowed != type(uint256).max)
allowance[from][msg.sender] = allowed - amount;
balanceOf[from] -= amount;
// Cannot overflow because the sum of all user
// balances can't exceed the max uint256 value.
unchecked {
balanceOf[to] += amount;
}
emit Transfer(from, to, amount);
return true;
}
/*//////////////////////////////////////////////////////////////
EIP-2612 LOGIC
//////////////////////////////////////////////////////////////*/
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) public virtual {
require(
deadline >= block.timestamp,
"PERMIT_DEADLINE_EXPIRED"
);
// Unchecked because the only math done is incrementing
// the owner's nonce which cannot realistically overflow.
unchecked {
address recoveredAddress = ecrecover(
keccak256(
abi.encodePacked(
"\x19\x01",
DOMAIN_SEPARATOR(),
keccak256(
abi.encode(
keccak256(
"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"
),
owner,
spender,
value,
nonces[owner]++,
deadline
)
)
)
),
v,
r,
s
);
require(
recoveredAddress != address(0) &&
recoveredAddress == owner,
"INVALID_SIGNER"
);
allowance[recoveredAddress][spender] = value;
}
emit Approval(owner, spender, value);
}
function DOMAIN_SEPARATOR()
public
view
virtual
returns (bytes32)
{
return
block.chainid == INITIAL_CHAIN_ID
? INITIAL_DOMAIN_SEPARATOR
: computeDomainSeparator();
}
function computeDomainSeparator()
internal
view
virtual
returns (bytes32)
{
return
keccak256(
abi.encode(
keccak256(
"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"
),
keccak256(bytes(name)),
keccak256("1"),
block.chainid,
address(this)
)
);
}
/*//////////////////////////////////////////////////////////////
INTERNAL MINT/BURN LOGIC
//////////////////////////////////////////////////////////////*/
function _mint(
address to,
uint256 amount
) internal virtual {
totalSupply += amount;
// Cannot overflow because the sum of all user
// balances can't exceed the max uint256 value.
unchecked {
balanceOf[to] += amount;
}
emit Transfer(address(0), to, amount);
}
function _burn(
address from,
uint256 amount
) internal virtual {
balanceOf[from] -= amount;
// Cannot underflow because a user's balance
// will never be larger than the total supply.
unchecked {
totalSupply -= amount;
}
emit Transfer(from, address(0), amount);
}
}

View File

@ -1,58 +0,0 @@
// SPDX-License-Identifier: MIT
pragma solidity >=0.8.4;
/// @notice Gas optimized verification of proof of inclusion for a leaf in a Merkle tree.
/// @author Solady
/// (https://github.com/vectorized/solady/blob/main/src/utils/MerkleProofLib.sol)
/// @author Modified from Solmate
/// (https://github.com/transmissions11/solmate/blob/main/src/utils/MerkleProofLib.sol)
/// @author Modified from OpenZeppelin
/// (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/cryptography/MerkleProof.sol)
library MerkleProofLib {
/// @dev Returns whether `leaf` exists in the Merkle tree with `root`, given `proof`.
function verify(
bytes32[] calldata proof,
bytes32 root,
bytes32 leaf
) internal pure returns (bool isValid) {
/// @solidity memory-safe-assembly
assembly {
if proof.length {
// Left shift by 5 is equivalent to multiplying by 0x20.
let end := add(
proof.offset,
shl(5, proof.length)
)
// Initialize `offset` to the offset of `proof` in the calldata.
let offset := proof.offset
// Iterate over proof elements to compute root hash.
for {
} 1 {
} {
// Slot of `leaf` in scratch space.
// If the condition is true: 0x20, otherwise: 0x00.
let scratch := shl(
5,
gt(leaf, calldataload(offset))
)
// Store elements to hash contiguously in scratch space.
// Scratch space is 64 bytes (0x00 - 0x3f) and both elements are 32 bytes.
mstore(scratch, leaf)
mstore(
xor(scratch, 0x20),
calldataload(offset)
)
// Reuse `leaf` to store the hash to reduce stack operations.
leaf := keccak256(0x00, 0x40)
offset := add(offset, 0x20)
if iszero(lt(offset, end)) {
break
}
}
}
isValid := eq(leaf, root)
}
}
}

View File

@ -1,34 +0,0 @@
// SPDX-License-Identifier: MIT
pragma solidity >=0.8.4;
/// @notice Reentrancy protection for smart contracts.
/// @author z0r0z.eth
/// @author Modified from Seaport
/// (https://github.com/ProjectOpenSea/seaport/blob/main/contracts/lib/ReentrancyGuard.sol)
/// @author Modified from Solmate
/// (https://github.com/Rari-Capital/solmate/blob/main/src/utils/ReentrancyGuard.sol)
abstract contract ReentrancyGuard {
error Reentrancy();
uint256 private guard = 1;
modifier nonReentrant() virtual {
setReentrancyGuard();
_;
clearReentrancyGuard();
}
/// @dev Check guard sentinel value and set it.
function setReentrancyGuard() internal virtual {
if (guard == 2) revert Reentrancy();
guard = 2;
}
/// @dev Unset sentinel value.
function clearReentrancyGuard() internal virtual {
guard = 1;
}
}

View File

@ -1,7 +1,7 @@
// SPDX-License-Identifier: MIT
pragma solidity >=0.8.4;
import { ERC20 } from "../tokens/ERC20.sol";
import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
/// @notice Safe ETH and ERC20 transfer library that gracefully handles missing return values.
/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/SafeTransferLib.sol)

View File

@ -38,6 +38,7 @@
"@nomicfoundation/hardhat-verify": "^2.1.0",
"@nomicfoundation/hardhat-viem": "^2.1.0",
"@nomicfoundation/ignition-core": "^0.15.13",
"@openzeppelin/contracts": "^5.4.0",
"@typechain/ethers-v6": "^0.5.1",
"@typechain/hardhat": "^9.1.0",
"@types/chai": "^4.3.20",

View File

@ -988,6 +988,13 @@ __metadata:
languageName: node
linkType: hard
"@openzeppelin/contracts@npm:^5.4.0":
version: 5.4.0
resolution: "@openzeppelin/contracts@npm:5.4.0"
checksum: 10/4f7f926ebd98279ba8223cae5d2cd38e0806e60e3e3a615c9d739ffab870ffab7a1e85f47092faa123c0f26d1699ca15252adea8bcdcaf360b21781acc93b218
languageName: node
linkType: hard
"@pkgjs/parseargs@npm:^0.11.0":
version: 0.11.0
resolution: "@pkgjs/parseargs@npm:0.11.0"
@ -4563,6 +4570,7 @@ __metadata:
"@nomicfoundation/hardhat-verify": "npm:^2.1.0"
"@nomicfoundation/hardhat-viem": "npm:^2.1.0"
"@nomicfoundation/ignition-core": "npm:^0.15.13"
"@openzeppelin/contracts": "npm:^5.4.0"
"@typechain/ethers-v6": "npm:^0.5.1"
"@typechain/hardhat": "npm:^9.1.0"
"@types/chai": "npm:^4.3.20"