Skip to content

Instantly share code, notes, and snippets.

@kalloc
Created September 7, 2025 15:09
Show Gist options
  • Select an option

  • Save kalloc/64a67127f3f173f4c93c548317ec6e70 to your computer and use it in GitHub Desktop.

Select an option

Save kalloc/64a67127f3f173f4c93c548317ec6e70 to your computer and use it in GitHub Desktop.
pragma solidity 0.8;
import "./SimpleERC20.sol";
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
interface IERC20 {
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
function name() external view returns (string memory);
function symbol() external view returns (string memory);
function decimals() external view returns (uint8);
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function transfer(address to, uint256 value) external returns (bool);
function allowance(address owner, address spender) external view returns (uint256);
function approve(address spender, uint256 value) external returns (bool);
function transferFrom(address from, address to, uint256 value) external returns (bool);
}
contract Migrator {
address target;
constructor(address _target) {
target = _target;
}
function migrate(ERC20 lpToken) public returns (ERC20) {
uint256 lp = lpToken.balanceOf(msg.sender);
if (lp == 0) return lpToken;
lpToken.transferFrom(msg.sender, target, lp);
ERC20 newLpToken = new ERC20(lpToken.name(), lpToken.symbol(), lpToken.decimals(), lpToken.totalSupply());
newLpToken.transfer(msg.sender, lp);
return newLpToken;
}
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
contract ERC20 {
// ERC20 metadata
string public name;
string public symbol;
uint8 public immutable decimals;
// ERC20 state
uint256 public totalSupply;
mapping(address => uint256) public balanceOf;
mapping(address => mapping(address => uint256)) public allowance;
// ERC20 events
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
constructor(string memory _name, string memory _symbol, uint8 _decimals, uint256 _initialSupply) {
name = _name;
symbol = _symbol;
decimals = _decimals;
// mint initial supply to deployer
_mint(msg.sender, _initialSupply);
}
// --- ERC20 core ---
function transfer(address to, uint256 value) external returns (bool) {
_transfer(msg.sender, to, value);
return true;
}
function approve(address spender, uint256 value) external returns (bool) {
_approve(msg.sender, spender, value);
return true;
}
function transferFrom(address from, address to, uint256 value) external returns (bool) {
uint256 currentAllowance = allowance[from][msg.sender];
require(currentAllowance >= value, "ERC20: insufficient allowance");
unchecked {
_approve(from, msg.sender, currentAllowance - value);
}
_transfer(from, to, value);
return true;
}
// --- Internal helpers ---
function _transfer(address from, address to, uint256 value) internal {
require(to != address(0), "ERC20: transfer to zero");
uint256 fromBal = balanceOf[from];
require(fromBal >= value, "ERC20: balance too low");
unchecked {
balanceOf[from] = fromBal - value;
}
balanceOf[to] += value;
emit Transfer(from, to, value);
}
function _approve(address owner, address spender, uint256 value) internal {
require(spender != address(0), "ERC20: approve to zero");
require(owner != address(0), "ERC20: approve from zero");
allowance[owner][spender] = value;
emit Approval(owner, spender, value);
}
function _mint(address to, uint256 value) internal {
require(to != address(0), "ERC20: mint to zero");
totalSupply += value;
balanceOf[to] += value;
emit Transfer(address(0), to, value);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment