Build a contract that lets me lock my erc-20 tokens somewhere.
Call the function BridgeETH (BridgeETH.sol)
// SPDX-License-Identifier: UNLICENSEDpragma solidity ^0.8.13;
import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol";import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";import { console } from "forge-std/console.sol";import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol";
contract BridgeETH is Ownable { uint256 public balance; address public tokenAddress;
mapping(address => uint256) public pendingBalance;
constructor(address _tokenAddress) Ownable(msg.sender) { tokenAddress = _tokenAddress; }
function deposit(IERC20 _tokenAddress, uint256 _amount) public { require(address(_tokenAddress) == tokenAddress); require(_tokenAddress.allowance(msg.sender, address(this)) >= _amount); require(_tokenAddress.transferFrom(msg.sender, address(this), _amount)); pendingBalance[msg.sender] += _amount; }
function withdraw(IERC20 _tokenAddress, uint256 _amount) public { require(pendingBalance[msg.sender] >= _amount); pendingBalance[msg.sender] -= _amount; _tokenAddress.transfer(msg.sender, _amount); }}
Also create an ERC20 token that you create that you need to lock (USDT.sol)
// SPDX-License-Identifier: UNLICENSEDpragma solidity ^0.8.13;
import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol";import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";import { console } from "forge-std/console.sol";import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol";
contract USDT is ERC20, Ownable { constructor() ERC20("USDT", "USDT") Ownable(msg.sender) {
}
function mint(address _to, uint256 _amount) public onlyOwner { _mint(_to, _amount); }}
Write tests for it (BridgeETH.t.sol)
// SPDX-License-Identifier: Unlicensepragma solidity ^0.8.13;
import "forge-std/Test.sol";
import "src/BridgeETH.sol";import "src/USDT.sol";import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
contract BridgeETHTest is Test { event Transfer(address indexed from, address indexed to, uint256 value);
BridgeETH bridge; USDT usdt;
function setUp() public { usdt = new USDT(); bridge = new BridgeETH(address(usdt)); }
function test_Deposit() public { usdt.mint(0x2966473D85A76A190697B5b9b66b769436EFE8e5, 200); vm.startPrank(0x2966473D85A76A190697B5b9b66b769436EFE8e5); usdt.approve(address(bridge), 200);
bridge.deposit(usdt, 200); assertEq(usdt.balanceOf(0x2966473D85A76A190697B5b9b66b769436EFE8e5), 0); assertEq(usdt.balanceOf(address(bridge)), 200);
bridge.withdraw(usdt, 100);
assertEq(usdt.balanceOf(0x2966473D85A76A190697B5b9b66b769436EFE8e5), 100); assertEq(usdt.balanceOf(address(bridge)), 100);
}
}