Skip to content

Commit 3b99bb3

Browse files
authored
Merge pull request #182 from Dhruv-Mishra/fix/addingMockSources
fix: Added sources for MockERC20 and MockERC721 tokens
2 parents f256eaf + 3283b7c commit 3b99bb3

File tree

3 files changed

+517
-2
lines changed

3 files changed

+517
-2
lines changed

src/Mocks.sol

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,5 +27,5 @@ import { MockFallback } from "./module-bases/mocks/MockFallback.sol";
2727
TOKENS
2828
//////////////////////////////////////////////////////////////*/
2929

30-
import { MockERC20 } from "forge-std/mocks/MockERC20.sol";
31-
import { MockERC721 } from "forge-std/mocks/MockERC721.sol";
30+
import { MockERC20 } from "./mocks/MockERC20.sol";
31+
import { MockERC721 } from "./mocks/MockERC721.sol";

src/mocks/MockERC20.sol

Lines changed: 257 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,257 @@
1+
// SPDX-License-Identifier: MIT
2+
pragma solidity >=0.8.23 <0.9.0;
3+
4+
import { IERC20 } from "forge-std/interfaces/IERC20.sol";
5+
6+
/// @notice This is a mock contract of the ERC20 standard for testing purposes only, it SHOULD NOT
7+
/// be used in production.
8+
/// @dev Forked from:
9+
/// https://github.com/transmissions11/solmate/blob/0384dbaaa4fcb5715738a9254a7c0a4cb62cf458/src/tokens/ERC20.sol
10+
contract MockERC20 is IERC20 {
11+
/*//////////////////////////////////////////////////////////////
12+
METADATA STORAGE
13+
//////////////////////////////////////////////////////////////*/
14+
15+
string internal _name;
16+
17+
string internal _symbol;
18+
19+
uint8 internal _decimals;
20+
21+
function name() external view override returns (string memory) {
22+
return _name;
23+
}
24+
25+
function symbol() external view override returns (string memory) {
26+
return _symbol;
27+
}
28+
29+
function decimals() external view override returns (uint8) {
30+
return _decimals;
31+
}
32+
33+
/*//////////////////////////////////////////////////////////////
34+
ERC20 STORAGE
35+
//////////////////////////////////////////////////////////////*/
36+
37+
uint256 internal _totalSupply;
38+
39+
mapping(address => uint256) internal _balanceOf;
40+
41+
mapping(address => mapping(address => uint256)) internal _allowance;
42+
43+
function totalSupply() external view override returns (uint256) {
44+
return _totalSupply;
45+
}
46+
47+
function balanceOf(address owner) external view override returns (uint256) {
48+
return _balanceOf[owner];
49+
}
50+
51+
function allowance(address owner, address spender) external view override returns (uint256) {
52+
return _allowance[owner][spender];
53+
}
54+
55+
/*//////////////////////////////////////////////////////////////
56+
EIP-2612 STORAGE
57+
//////////////////////////////////////////////////////////////*/
58+
59+
uint256 internal INITIAL_CHAIN_ID;
60+
61+
bytes32 internal INITIAL_DOMAIN_SEPARATOR;
62+
63+
mapping(address => uint256) public nonces;
64+
65+
/*//////////////////////////////////////////////////////////////
66+
INITIALIZE
67+
//////////////////////////////////////////////////////////////*/
68+
69+
/// @dev A bool to track whether the contract has been initialized.
70+
bool private initialized;
71+
72+
/// @dev To hide constructor warnings across solc versions due to different constructor
73+
/// visibility requirements and
74+
/// syntaxes, we add an initialization function that can be called only once.
75+
function initialize(string memory name_, string memory symbol_, uint8 decimals_) public {
76+
require(!initialized, "ALREADY_INITIALIZED");
77+
78+
_name = name_;
79+
_symbol = symbol_;
80+
_decimals = decimals_;
81+
82+
INITIAL_CHAIN_ID = _pureChainId();
83+
INITIAL_DOMAIN_SEPARATOR = computeDomainSeparator();
84+
85+
initialized = true;
86+
}
87+
88+
/*//////////////////////////////////////////////////////////////
89+
ERC20 LOGIC
90+
//////////////////////////////////////////////////////////////*/
91+
92+
function approve(address spender, uint256 amount) public virtual override returns (bool) {
93+
_allowance[msg.sender][spender] = amount;
94+
95+
emit Approval(msg.sender, spender, amount);
96+
97+
return true;
98+
}
99+
100+
function transfer(address to, uint256 amount) public virtual override returns (bool) {
101+
_balanceOf[msg.sender] = _sub(_balanceOf[msg.sender], amount);
102+
_balanceOf[to] = _add(_balanceOf[to], amount);
103+
104+
emit Transfer(msg.sender, to, amount);
105+
106+
return true;
107+
}
108+
109+
function transferFrom(
110+
address from,
111+
address to,
112+
uint256 amount
113+
)
114+
public
115+
virtual
116+
override
117+
returns (bool)
118+
{
119+
uint256 allowed = _allowance[from][msg.sender]; // Saves gas for limited approvals.
120+
121+
if (allowed != ~uint256(0)) _allowance[from][msg.sender] = _sub(allowed, amount);
122+
123+
_balanceOf[from] = _sub(_balanceOf[from], amount);
124+
_balanceOf[to] = _add(_balanceOf[to], amount);
125+
126+
emit Transfer(from, to, amount);
127+
128+
return true;
129+
}
130+
131+
/*//////////////////////////////////////////////////////////////
132+
EIP-2612 LOGIC
133+
//////////////////////////////////////////////////////////////*/
134+
135+
function permit(
136+
address owner,
137+
address spender,
138+
uint256 value,
139+
uint256 deadline,
140+
uint8 v,
141+
bytes32 r,
142+
bytes32 s
143+
)
144+
public
145+
virtual
146+
{
147+
require(deadline >= block.timestamp, "PERMIT_DEADLINE_EXPIRED");
148+
149+
address recoveredAddress = ecrecover(
150+
keccak256(
151+
abi.encodePacked(
152+
"\x19\x01",
153+
DOMAIN_SEPARATOR(),
154+
keccak256(
155+
abi.encode(
156+
keccak256(
157+
"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"
158+
),
159+
owner,
160+
spender,
161+
value,
162+
nonces[owner]++,
163+
deadline
164+
)
165+
)
166+
)
167+
),
168+
v,
169+
r,
170+
s
171+
);
172+
173+
require(recoveredAddress != address(0) && recoveredAddress == owner, "INVALID_SIGNER");
174+
175+
_allowance[recoveredAddress][spender] = value;
176+
177+
emit Approval(owner, spender, value);
178+
}
179+
180+
function DOMAIN_SEPARATOR() public view virtual returns (bytes32) {
181+
return
182+
_pureChainId() == INITIAL_CHAIN_ID ? INITIAL_DOMAIN_SEPARATOR : computeDomainSeparator();
183+
}
184+
185+
function computeDomainSeparator() internal view virtual returns (bytes32) {
186+
return keccak256(
187+
abi.encode(
188+
keccak256(
189+
"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"
190+
),
191+
keccak256(bytes(_name)),
192+
keccak256("1"),
193+
_pureChainId(),
194+
address(this)
195+
)
196+
);
197+
}
198+
199+
/*//////////////////////////////////////////////////////////////
200+
INTERNAL MINT/BURN LOGIC
201+
//////////////////////////////////////////////////////////////*/
202+
203+
function _mint(address to, uint256 amount) internal virtual {
204+
_totalSupply = _add(_totalSupply, amount);
205+
_balanceOf[to] = _add(_balanceOf[to], amount);
206+
207+
emit Transfer(address(0), to, amount);
208+
}
209+
210+
function _burn(address from, uint256 amount) internal virtual {
211+
_balanceOf[from] = _sub(_balanceOf[from], amount);
212+
_totalSupply = _sub(_totalSupply, amount);
213+
214+
emit Transfer(from, address(0), amount);
215+
}
216+
217+
/*//////////////////////////////////////////////////////////////
218+
INTERNAL SAFE MATH LOGIC
219+
//////////////////////////////////////////////////////////////*/
220+
221+
function _add(uint256 a, uint256 b) internal pure returns (uint256) {
222+
uint256 c = a + b;
223+
require(c >= a, "ERC20: addition overflow");
224+
return c;
225+
}
226+
227+
function _sub(uint256 a, uint256 b) internal pure returns (uint256) {
228+
require(a >= b, "ERC20: subtraction underflow");
229+
return a - b;
230+
}
231+
232+
/*//////////////////////////////////////////////////////////////
233+
HELPERS
234+
//////////////////////////////////////////////////////////////*/
235+
236+
// We use this complex approach of `_viewChainId` and `_pureChainId` to ensure there are no
237+
// compiler warnings when accessing chain ID in any solidity version supported by forge-std. We
238+
// can't simply access the chain ID in a normal view or pure function because the solc View Pure
239+
// Checker changed `chainid` from pure to view in 0.8.0.
240+
function _viewChainId() private view returns (uint256 chainId) {
241+
// Assembly required since `block.chainid` was introduced in 0.8.0.
242+
assembly {
243+
chainId := chainid()
244+
}
245+
246+
address(this); // Silence warnings in older Solc versions.
247+
}
248+
249+
function _pureChainId() private pure returns (uint256 chainId) {
250+
function() internal view returns (uint256) fnIn = _viewChainId;
251+
function() internal pure returns (uint256) pureChainId;
252+
assembly {
253+
pureChainId := fnIn
254+
}
255+
chainId = pureChainId();
256+
}
257+
}

0 commit comments

Comments
 (0)