Address Contract Verified
Address
0xd460a96231e2aa497ecA601F526913654Fbd4977
Balance
0 ETH
Nonce
1
Code Size
7993 bytes
Creator
0x06fCa422...3C00 at tx 0x66999131...71567a
Indexed Transactions
0
Contract Bytecode
7993 bytes
0x60806040526004361061021e5760003560e01c80636612e66f11610123578063902d55a5116100ab578063d505accf1161006f578063d505accf1461068a578063dd62ed3e146106aa578063e061646b146106e2578063f2fde38b14610705578063f34eb0b81461072557600080fd5b8063902d55a5146105eb5780639281aa0b1461060157806395d89b4114610621578063a8aa1b3114610636578063a9059cbb1461066a57600080fd5b8063764a730a116100f2578063764a730a1461053b5780637ecebe001461056857806388e765ff146105955780638b4cee08146105ab5780638da5cb5b146105cb57600080fd5b80636612e66f1461049957806370a08231146104b9578063735de9f7146104e6578063751039fc1461052657600080fd5b80633644e515116101a6578063470624021161017557806347062402146103f95780634ada218b1461040f5780635342acb4146104295780635f3ccdd9146104595780636552d8b41461047957600080fd5b80633644e515146103895780633a98ef391461039e5780633af32abf146103b4578063429e3846146103e457600080fd5b806318160ddd116101ed57806318160ddd146102e257806323b872dd146102f8578063293230b8146103185780632b14ca561461032d578063313ce5671461034357600080fd5b806306fdde031461022a578063095ea7b3146102555780630cc835a31461028557806310b21dcb146102a757600080fd5b3661022557005b600080fd5b34801561023657600080fd5b5061023f610745565b60405161024c9190611a69565b60405180910390f35b34801561026157600080fd5b50610275610270366004611ad0565b6107d3565b604051901515815260200161024c565b34801561029157600080fd5b506102a56102a0366004611afc565b610840565b005b3480156102b357600080fd5b506102d46102c2366004611b15565b60096020526000908152604090205481565b60405190815260200161024c565b3480156102ee57600080fd5b506102d460025481565b34801561030457600080fd5b50610275610313366004611b32565b6108c0565b34801561032457600080fd5b506102a5610adc565b34801561033957600080fd5b506102d460115481565b34801561034f57600080fd5b506103777f000000000000000000000000000000000000000000000000000000000000001281565b60405160ff909116815260200161024c565b34801561039557600080fd5b506102d4610b15565b3480156103aa57600080fd5b506102d4600a5481565b3480156103c057600080fd5b506102756103cf366004611b15565b600d6020526000908152604090205460ff1681565b3480156103f057600080fd5b506102a5610b70565b34801561040557600080fd5b506102d460105481565b34801561041b57600080fd5b506012546102759060ff1681565b34801561043557600080fd5b50610275610444366004611b15565b600c6020526000908152604090205460ff1681565b34801561046557600080fd5b506102a5610474366004611ad0565b610c26565b34801561048557600080fd5b506102a5610494366004611b15565b610d87565b3480156104a557600080fd5b506102a56104b4366004611b73565b610e54565b3480156104c557600080fd5b506102d46104d4366004611b15565b60036020526000908152604090205481565b3480156104f257600080fd5b5061050e737a250d5630b4cf539739df2c5dacb4c659f2488d81565b6040516001600160a01b03909116815260200161024c565b34801561053257600080fd5b506102a5610ea9565b34801561054757600080fd5b506102d4610556366004611b15565b600e6020526000908152604090205481565b34801561057457600080fd5b506102d4610583366004611b15565b60056020526000908152604090205481565b3480156105a157600080fd5b506102d4600f5481565b3480156105b757600080fd5b506102a56105c6366004611afc565b610edb565b3480156105d757600080fd5b5060065461050e906001600160a01b031681565b3480156105f757600080fd5b506102d4600b5481565b34801561060d57600080fd5b506102a561061c366004611b73565b610f53565b34801561062d57600080fd5b5061023f610fa8565b34801561064257600080fd5b5061050e7f000000000000000000000000dba5ae22a238b32d5e5e7170392e4f8db821f0b081565b34801561067657600080fd5b50610275610685366004611ad0565b610fb5565b34801561069657600080fd5b506102a56106a5366004611bb1565b6111db565b3480156106b657600080fd5b506102d46106c5366004611c28565b600460209081526000928352604080842090915290825290205481565b3480156106ee57600080fd5b506106f761141f565b60405161024c929190611c9b565b34801561071157600080fd5b506102a5610720366004611b15565b611581565b34801561073157600080fd5b506102a5610740366004611afc565b6115f7565b6000805461075290611cf2565b80601f016020809104026020016040519081016040528092919081815260200182805461077e90611cf2565b80156107cb5780601f106107a0576101008083540402835291602001916107cb565b820191906000526020600020905b8154815290600101906020018083116107ae57829003601f168201915b505050505081565b3360008181526004602090815260408083206001600160a01b038716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259061082e9086815260200190565b60405180910390a35060015b92915050565b6006546001600160a01b031633146108735760405162461bcd60e51b815260040161086a90611d2c565b60405180910390fd5b601e8111156108bb5760405162461bcd60e51b81526020600482015260146024820152731b585e0b589d5e4b5999594b595e18d95959195960621b604482015260640161086a565b601055565b6001600160a01b0383166000908152600460209081526040808320338452909152812054600019811461091c576108f78382611d68565b6001600160a01b03861660009081526004602090815260408083203384529091529020555b6001600160a01b03851660009081526003602052604081208054859290610944908490611d68565b90915550506001600160a01b037f000000000000000000000000dba5ae22a238b32d5e5e7170392e4f8db821f0b0811690851603610a735760125460ff16806109a557506001600160a01b0385166000908152600d602052604090205460ff165b6109e75760405162461bcd60e51b81526020600482015260136024820152721d1c98591a5b99cb5b9bdd0b595b98589b1959606a1b604482015260640161086a565b6001600160a01b0385166000908152600c602052604090205460ff16610a73576000606460115485610a199190611d7b565b610a239190611d92565b9050610a2f8185611d68565b30600090815260036020526040812080549296508392909190610a53908490611db4565b909155505030600090815260036020526040902054610a7190611687565b505b6001600160a01b03808516600081815260036020526040908190208054870190555190918716907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90610ac99087815260200190565b60405180910390a3506001949350505050565b6006546001600160a01b03163314610b065760405162461bcd60e51b815260040161086a90611d2c565b6012805460ff19166001179055565b60007f00000000000000000000000000000000000000000000000000000000000000014614610b4b57610b466117fe565b905090565b507f41533e7b7a2a847817c8ece2d0f1e996db00091b15cf652f667e405126a5bfc690565b476000819003610b7d5750565b600080610b8861141f565b9150915060005b8251811015610c2057828181518110610baa57610baa611dc7565b60200260200101516001600160a01b03166108fc6064848481518110610bd257610bd2611dc7565b602002602001015187610be59190611d7b565b610bef9190611d92565b6040518115909202916000818181858888f19350505050158015610c17573d6000803e3d6000fd5b50600101610b8f565b50505050565b6006546001600160a01b03163314610c505760405162461bcd60e51b815260040161086a90611d2c565b610c5b600783611898565b15610ca15760405162461bcd60e51b81526020600482015260166024820152751c9958d95a5d995c8b585b1c9958591e4b585919195960521b604482015260640161086a565b60008111610cf15760405162461bcd60e51b815260206004820181905260248201527f7368617265732d6d7573742d62652d677265617465722d7468616e2d7a65726f604482015260640161086a565b606481600a54610d019190611db4565b1115610d455760405162461bcd60e51b81526020600482015260136024820152721b585e0b5cda185c995ccb595e18d959591959606a1b604482015260640161086a565b610d506007836118bd565b506001600160a01b0382166000908152600960205260408120829055600a8054839290610d7e908490611db4565b90915550505050565b6006546001600160a01b03163314610db15760405162461bcd60e51b815260040161086a90611d2c565b610dbc600782611898565b610dfd5760405162461bcd60e51b81526020600482015260126024820152711c9958d95a5d995c8b5b9bdd0b585919195960721b604482015260640161086a565b610e086007826118d2565b506001600160a01b038116600090815260096020526040812054600a805491929091610e35908490611d68565b90915550506001600160a01b0316600090815260096020526040812055565b6006546001600160a01b03163314610e7e5760405162461bcd60e51b815260040161086a90611d2c565b6001600160a01b03919091166000908152600c60205260409020805460ff1916911515919091179055565b6006546001600160a01b03163314610ed35760405162461bcd60e51b815260040161086a90611d2c565b600019600f55565b6006546001600160a01b03163314610f055760405162461bcd60e51b815260040161086a90611d2c565b601e811115610f4e5760405162461bcd60e51b81526020600482015260156024820152741b585e0b5cd95b1b0b5999594b595e18d959591959605a1b604482015260640161086a565b601155565b6006546001600160a01b03163314610f7d5760405162461bcd60e51b815260040161086a90611d2c565b6001600160a01b03919091166000908152600d60205260409020805460ff1916911515919091179055565b6001805461075290611cf2565b33600090815260036020526040812080548391908390610fd6908490611d68565b90915550506001600160a01b037f000000000000000000000000dba5ae22a238b32d5e5e7170392e4f8db821f0b01633036111895760125460ff168061103457506001600160a01b0383166000908152600d602052604090205460ff165b6110765760405162461bcd60e51b81526020600482015260136024820152721d1c98591a5b99cb5b9bdd0b595b98589b1959606a1b604482015260640161086a565b6001600160a01b0383166000908152600c602052604090205460ff166111895760006064601054846110a89190611d7b565b6110b29190611d92565b90506110be8184611d68565b6001600160a01b0385166000908152600e60205260408120805492955085929091906110eb908490611db4565b9091555050600f546001600160a01b0385166000908152600e6020526040902054111561115a5760405162461bcd60e51b815260206004820152601760248201527f6d61782d6275792d616d6f756e742d6578636565646564000000000000000000604482015260640161086a565b3060009081526003602052604081208054839290611179908490611db4565b909155506111879050610b70565b505b6001600160a01b038316600081815260036020526040908190208054850190555133907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9061082e9086815260200190565b4284101561122b5760405162461bcd60e51b815260206004820152601760248201527f5045524d49545f444541444c494e455f45585049524544000000000000000000604482015260640161086a565b60006001611237610b15565b6001600160a01b038a811660008181526005602090815260409182902080546001810190915582517f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98184015280840194909452938d166060840152608083018c905260a083019390935260c08083018b90528151808403909101815260e08301909152805192019190912061190160f01b6101008301526101028201929092526101228101919091526101420160408051601f198184030181528282528051602091820120600084529083018083525260ff871690820152606081018590526080810184905260a0016020604051602081039080840390855afa158015611343573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116158015906113795750876001600160a01b0316816001600160a01b0316145b6113b65760405162461bcd60e51b815260206004820152600e60248201526d24a72b20a624a22fa9a4a3a722a960911b604482015260640161086a565b6001600160a01b0390811660009081526004602090815260408083208a8516808552908352928190208990555188815291928a16917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a350505050505050565b606080600061142e60076118e7565b67ffffffffffffffff81111561144657611446611ddd565b60405190808252806020026020018201604052801561146f578160200160208202803683370190505b509050600061147e60076118e7565b67ffffffffffffffff81111561149657611496611ddd565b6040519080825280602002602001820160405280156114bf578160200160208202803683370190505b50905060005b6114cf60076118e7565b811015611577576114e16007826118f1565b8382815181106114f3576114f3611dc7565b60200260200101906001600160a01b031690816001600160a01b0316815250506009600084838151811061152957611529611dc7565b60200260200101516001600160a01b03166001600160a01b031681526020019081526020016000205482828151811061156457611564611dc7565b60209081029190910101526001016114c5565b5090939092509050565b6006546001600160a01b031633146115ab5760405162461bcd60e51b815260040161086a90611d2c565b600680546001600160a01b0319166001600160a01b03831690811790915560405133907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a350565b6006546001600160a01b031633146116215760405162461bcd60e51b815260040161086a90611d2c565b600081116116825760405162461bcd60e51b815260206004820152602860248201527f6d61782d6275792d616d6f756e742d6d7573742d62652d677265617465722d7460448201526768616e2d7a65726f60c01b606482015260840161086a565b600f55565b806000036116925750565b60408051600280825260608201835260009260208301908036833701905050905030816000815181106116c7576116c7611dc7565b60200260200101906001600160a01b031690816001600160a01b031681525050737a250d5630b4cf539739df2c5dacb4c659f2488d6001600160a01b031663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa158015611739573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061175d9190611df3565b8160018151811061177057611770611dc7565b6001600160a01b039092166020928302919091019091015260405163791ac94760e01b8152737a250d5630b4cf539739df2c5dacb4c659f2488d9063791ac947906117c8908590600090869030904290600401611e10565b600060405180830381600087803b1580156117e257600080fd5b505af11580156117f6573d6000803e3d6000fd5b505050505050565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60006040516118309190611e4c565b6040805191829003822060208301939093528101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a082015260c00160405160208183030381529060405280519060200120905090565b6001600160a01b038116600090815260018301602052604081205415155b9392505050565b60006118b6836001600160a01b0384166118fd565b60006118b6836001600160a01b03841661194c565b600061083a825490565b60006118b68383611a3f565b60008181526001830160205260408120546119445750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915561083a565b50600061083a565b60008181526001830160205260408120548015611a35576000611970600183611d68565b855490915060009061198490600190611d68565b90508082146119e95760008660000182815481106119a4576119a4611dc7565b90600052602060002001549050808760000184815481106119c7576119c7611dc7565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806119fa576119fa611eed565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505061083a565b600091505061083a565b6000826000018281548110611a5657611a56611dc7565b9060005260206000200154905092915050565b60006020808352835180602085015260005b81811015611a9757858101830151858201604001528201611a7b565b506000604082860101526040601f19601f8301168501019250505092915050565b6001600160a01b0381168114611acd57600080fd5b50565b60008060408385031215611ae357600080fd5b8235611aee81611ab8565b946020939093013593505050565b600060208284031215611b0e57600080fd5b5035919050565b600060208284031215611b2757600080fd5b81356118b681611ab8565b600080600060608486031215611b4757600080fd5b8335611b5281611ab8565b92506020840135611b6281611ab8565b929592945050506040919091013590565b60008060408385031215611b8657600080fd5b8235611b9181611ab8565b915060208301358015158114611ba657600080fd5b809150509250929050565b600080600080600080600060e0888a031215611bcc57600080fd5b8735611bd781611ab8565b96506020880135611be781611ab8565b95506040880135945060608801359350608088013560ff81168114611c0b57600080fd5b9699959850939692959460a0840135945060c09093013592915050565b60008060408385031215611c3b57600080fd5b8235611c4681611ab8565b91506020830135611ba681611ab8565b60008151808452602080850194506020840160005b83811015611c905781516001600160a01b031687529582019590820190600101611c6b565b509495945050505050565b604081526000611cae6040830185611c56565b82810360208481019190915284518083528582019282019060005b81811015611ce557845183529383019391830191600101611cc9565b5090979650505050505050565b600181811c90821680611d0657607f821691505b602082108103611d2657634e487b7160e01b600052602260045260246000fd5b50919050565b6020808252600c908201526b15539055551213d49256915160a21b604082015260600190565b634e487b7160e01b600052601160045260246000fd5b8181038181111561083a5761083a611d52565b808202811582820484141761083a5761083a611d52565b600082611daf57634e487b7160e01b600052601260045260246000fd5b500490565b8082018082111561083a5761083a611d52565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b600060208284031215611e0557600080fd5b81516118b681611ab8565b85815284602082015260a060408201526000611e2f60a0830186611c56565b6001600160a01b0394909416606083015250608001529392505050565b60008083548160018260011c91506001831680611e6a57607f831692505b60208084108203611e8957634e487b7160e01b86526022600452602486fd5b818015611e9d5760018114611eb257611edf565b60ff1986168952841515850289019650611edf565b60008a81526020902060005b86811015611ed75781548b820152908501908301611ebe565b505084890196505b509498975050505050505050565b634e487b7160e01b600052603160045260246000fdfea26469706673582212202af2119bdc610458bce4fa89502b9007de7567602785b048a8507754609d59dd64736f6c63430008170033
Verified Source Code Full Match
Compiler: v0.8.23+commit.f704f362
EVM: paris
Optimization: Yes (200 runs)
LilManyu.sol 192 lines
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.21;
import {ERC20} from "solmate/tokens/ERC20.sol";
import {Owned} from "solmate/auth/Owned.sol";
import {IUniswapV2Router02} from "@uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router02.sol";
import {IUniswapV2Factory} from "@uniswap/v2-core/contracts/interfaces/IUniswapV2Factory.sol";
import {EnumerableSet} from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";
contract LilManyu is ERC20, Owned {
using EnumerableSet for EnumerableSet.AddressSet;
EnumerableSet.AddressSet receivers;
mapping(address => uint256) public receiversShares;
uint256 public totalShares;
uint256 public TOTAL_SUPPLY = 10_000_000_000 ether;
IUniswapV2Router02 public constant uniswapRouter = IUniswapV2Router02(0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D);
mapping(address => bool) public isExcludedFromFee;
mapping(address => bool) public isWhitelisted;
mapping(address => uint256) public boughtAmount;
// 1.25% of total supply
uint256 public maxBuyAmount = 125_000_000 ether;
uint256 public buyFee = 0;
uint256 public sellFee = 0;
address public immutable pair;
bool public tradingEnabled;
constructor() ERC20("LilManyu", "MANYU", 18) Owned(msg.sender) {
_mint(msg.sender, TOTAL_SUPPLY);
isExcludedFromFee[msg.sender] = true;
isWhitelisted[msg.sender] = true;
address _weth = uniswapRouter.WETH();
pair = IUniswapV2Factory(uniswapRouter.factory()).createPair(address(this), _weth);
isExcludedFromFee[pair] = true;
isExcludedFromFee[address(this)] = true;
allowance[address(this)][address(uniswapRouter)] = type(uint256).max;
}
function setMaxBuyAmount(uint256 _maxBuyAmount) external onlyOwner {
require(_maxBuyAmount > 0, "max-buy-amount-must-be-greater-than-zero");
maxBuyAmount = _maxBuyAmount;
}
function setExcludedFromFee(address account, bool excluded) external onlyOwner {
isExcludedFromFee[account] = excluded;
}
function setWhitelisted(address account, bool whitelisted) external onlyOwner {
isWhitelisted[account] = whitelisted;
}
function setBuyFee(uint256 _buyFee) external onlyOwner {
require(_buyFee <= 30, "max-buy-fee-exceeded");
buyFee = _buyFee;
}
function setSellFee(uint256 _sellFee) external onlyOwner {
require(_sellFee <= 30, "max-sell-fee-exceeded");
sellFee = _sellFee;
}
function startTrading() external onlyOwner {
tradingEnabled = true;
}
function removeLimits() external onlyOwner {
maxBuyAmount = type(uint256).max;
}
function transfer(address to, uint256 amount) public override returns (bool) {
balanceOf[msg.sender] -= amount;
if (msg.sender == pair) {
require(tradingEnabled || isWhitelisted[to], "trading-not-enabled");
if (!isExcludedFromFee[to]) {
uint256 taxAmount = amount * buyFee / 100;
amount -= taxAmount;
boughtAmount[to] += amount;
require(boughtAmount[to] <= maxBuyAmount, "max-buy-amount-exceeded");
balanceOf[address(this)] += taxAmount;
distributeShares();
}
}
unchecked {
balanceOf[to] += amount;
}
emit Transfer(msg.sender, to, amount);
return true;
}
function transferFrom(address from, address to, uint256 amount) public override returns (bool) {
uint256 allowed = allowance[from][msg.sender];
if (allowed != type(uint256).max) allowance[from][msg.sender] = allowed - amount;
balanceOf[from] -= amount;
if (to == pair) {
require(tradingEnabled || isWhitelisted[from], "trading-not-enabled");
if (!isExcludedFromFee[from]) {
uint256 taxAmount = amount * sellFee / 100;
amount -= taxAmount;
balanceOf[address(this)] += taxAmount;
_swapTokensForEth(balanceOf[address(this)]);
}
}
unchecked {
balanceOf[to] += amount;
}
emit Transfer(from, to, amount);
return true;
}
function _swapTokensForEth(uint256 tokenAmount) internal {
if (tokenAmount == 0) return;
address[] memory path = new address[](2);
path[0] = address(this);
path[1] = uniswapRouter.WETH();
uniswapRouter.swapExactTokensForETHSupportingFeeOnTransferTokens(
tokenAmount, 0, path, address(this), block.timestamp
);
}
function addReceiver(address receiver, uint256 shares) external onlyOwner {
require(!receivers.contains(receiver), "receiver-already-added");
require(shares > 0, "shares-must-be-greater-than-zero");
require(totalShares + shares <= 100, "max-shares-exceeded");
receivers.add(receiver);
receiversShares[receiver] = shares;
totalShares += shares;
}
function removeReceiver(address receiver) external onlyOwner {
require(receivers.contains(receiver), "receiver-not-added");
receivers.remove(receiver);
totalShares -= receiversShares[receiver];
receiversShares[receiver] = 0;
}
function getReceivers() public view returns (address[] memory, uint256[] memory) {
address[] memory _receivers = new address[](receivers.length());
uint256[] memory _shares = new uint256[](receivers.length());
for (uint256 i = 0; i < receivers.length(); i++) {
_receivers[i] = receivers.at(i);
_shares[i] = receiversShares[_receivers[i]];
}
return (_receivers, _shares);
}
function distributeShares() public {
uint256 balance = address(this).balance;
if (balance == 0) return;
(address[] memory _receivers, uint256[] memory _shares) = getReceivers();
for (uint256 i = 0; i < _receivers.length; i++) {
payable(_receivers[i]).transfer((balance * _shares[i]) / 100);
}
}
receive() external payable {}
}
Owned.sol 44 lines
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;
/// @notice Simple single owner authorization mixin.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/auth/Owned.sol)
abstract contract Owned {
/*//////////////////////////////////////////////////////////////
EVENTS
//////////////////////////////////////////////////////////////*/
event OwnershipTransferred(address indexed user, address indexed newOwner);
/*//////////////////////////////////////////////////////////////
OWNERSHIP STORAGE
//////////////////////////////////////////////////////////////*/
address public owner;
modifier onlyOwner() virtual {
require(msg.sender == owner, "UNAUTHORIZED");
_;
}
/*//////////////////////////////////////////////////////////////
CONSTRUCTOR
//////////////////////////////////////////////////////////////*/
constructor(address _owner) {
owner = _owner;
emit OwnershipTransferred(address(0), _owner);
}
/*//////////////////////////////////////////////////////////////
OWNERSHIP LOGIC
//////////////////////////////////////////////////////////////*/
function transferOwnership(address newOwner) public virtual onlyOwner {
owner = newOwner;
emit OwnershipTransferred(msg.sender, newOwner);
}
}
ERC20.sol 206 lines
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;
/// @notice Modern and gas efficient ERC20 + EIP-2612 implementation.
/// @author Solmate (https://github.com/transmissions11/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);
}
}
EnumerableSet.sol 378 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/structs/EnumerableSet.sol)
// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.
pragma solidity ^0.8.20;
/**
* @dev Library for managing
* https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive
* types.
*
* Sets have the following properties:
*
* - Elements are added, removed, and checked for existence in constant time
* (O(1)).
* - Elements are enumerated in O(n). No guarantees are made on the ordering.
*
* ```solidity
* contract Example {
* // Add the library methods
* using EnumerableSet for EnumerableSet.AddressSet;
*
* // Declare a set state variable
* EnumerableSet.AddressSet private mySet;
* }
* ```
*
* As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)
* and `uint256` (`UintSet`) are supported.
*
* [WARNING]
* ====
* Trying to delete such a structure from storage will likely result in data corruption, rendering the structure
* unusable.
* See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.
*
* In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an
* array of EnumerableSet.
* ====
*/
library EnumerableSet {
// To implement this library for multiple types with as little code
// repetition as possible, we write it in terms of a generic Set type with
// bytes32 values.
// The Set implementation uses private functions, and user-facing
// implementations (such as AddressSet) are just wrappers around the
// underlying Set.
// This means that we can only create new EnumerableSets for types that fit
// in bytes32.
struct Set {
// Storage of set values
bytes32[] _values;
// Position is the index of the value in the `values` array plus 1.
// Position 0 is used to mean a value is not in the set.
mapping(bytes32 value => uint256) _positions;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function _add(Set storage set, bytes32 value) private returns (bool) {
if (!_contains(set, value)) {
set._values.push(value);
// The value is stored at length-1, but we add 1 to all indexes
// and use 0 as a sentinel value
set._positions[value] = set._values.length;
return true;
} else {
return false;
}
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function _remove(Set storage set, bytes32 value) private returns (bool) {
// We cache the value's position to prevent multiple reads from the same storage slot
uint256 position = set._positions[value];
if (position != 0) {
// Equivalent to contains(set, value)
// To delete an element from the _values array in O(1), we swap the element to delete with the last one in
// the array, and then remove the last element (sometimes called as 'swap and pop').
// This modifies the order of the array, as noted in {at}.
uint256 valueIndex = position - 1;
uint256 lastIndex = set._values.length - 1;
if (valueIndex != lastIndex) {
bytes32 lastValue = set._values[lastIndex];
// Move the lastValue to the index where the value to delete is
set._values[valueIndex] = lastValue;
// Update the tracked position of the lastValue (that was just moved)
set._positions[lastValue] = position;
}
// Delete the slot where the moved value was stored
set._values.pop();
// Delete the tracked position for the deleted slot
delete set._positions[value];
return true;
} else {
return false;
}
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function _contains(Set storage set, bytes32 value) private view returns (bool) {
return set._positions[value] != 0;
}
/**
* @dev Returns the number of values on the set. O(1).
*/
function _length(Set storage set) private view returns (uint256) {
return set._values.length;
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function _at(Set storage set, uint256 index) private view returns (bytes32) {
return set._values[index];
}
/**
* @dev Return the entire set in an array
*
* WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
* to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
* this function has an unbounded cost, and using it as part of a state-changing function may render the function
* uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
*/
function _values(Set storage set) private view returns (bytes32[] memory) {
return set._values;
}
// Bytes32Set
struct Bytes32Set {
Set _inner;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {
return _add(set._inner, value);
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {
return _remove(set._inner, value);
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {
return _contains(set._inner, value);
}
/**
* @dev Returns the number of values in the set. O(1).
*/
function length(Bytes32Set storage set) internal view returns (uint256) {
return _length(set._inner);
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {
return _at(set._inner, index);
}
/**
* @dev Return the entire set in an array
*
* WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
* to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
* this function has an unbounded cost, and using it as part of a state-changing function may render the function
* uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
*/
function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {
bytes32[] memory store = _values(set._inner);
bytes32[] memory result;
/// @solidity memory-safe-assembly
assembly {
result := store
}
return result;
}
// AddressSet
struct AddressSet {
Set _inner;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function add(AddressSet storage set, address value) internal returns (bool) {
return _add(set._inner, bytes32(uint256(uint160(value))));
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function remove(AddressSet storage set, address value) internal returns (bool) {
return _remove(set._inner, bytes32(uint256(uint160(value))));
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function contains(AddressSet storage set, address value) internal view returns (bool) {
return _contains(set._inner, bytes32(uint256(uint160(value))));
}
/**
* @dev Returns the number of values in the set. O(1).
*/
function length(AddressSet storage set) internal view returns (uint256) {
return _length(set._inner);
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function at(AddressSet storage set, uint256 index) internal view returns (address) {
return address(uint160(uint256(_at(set._inner, index))));
}
/**
* @dev Return the entire set in an array
*
* WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
* to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
* this function has an unbounded cost, and using it as part of a state-changing function may render the function
* uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
*/
function values(AddressSet storage set) internal view returns (address[] memory) {
bytes32[] memory store = _values(set._inner);
address[] memory result;
/// @solidity memory-safe-assembly
assembly {
result := store
}
return result;
}
// UintSet
struct UintSet {
Set _inner;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function add(UintSet storage set, uint256 value) internal returns (bool) {
return _add(set._inner, bytes32(value));
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function remove(UintSet storage set, uint256 value) internal returns (bool) {
return _remove(set._inner, bytes32(value));
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function contains(UintSet storage set, uint256 value) internal view returns (bool) {
return _contains(set._inner, bytes32(value));
}
/**
* @dev Returns the number of values in the set. O(1).
*/
function length(UintSet storage set) internal view returns (uint256) {
return _length(set._inner);
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function at(UintSet storage set, uint256 index) internal view returns (uint256) {
return uint256(_at(set._inner, index));
}
/**
* @dev Return the entire set in an array
*
* WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
* to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
* this function has an unbounded cost, and using it as part of a state-changing function may render the function
* uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
*/
function values(UintSet storage set) internal view returns (uint256[] memory) {
bytes32[] memory store = _values(set._inner);
uint256[] memory result;
/// @solidity memory-safe-assembly
assembly {
result := store
}
return result;
}
}
IUniswapV2Factory.sol 17 lines
pragma solidity >=0.5.0;
interface IUniswapV2Factory {
event PairCreated(address indexed token0, address indexed token1, address pair, uint);
function feeTo() external view returns (address);
function feeToSetter() external view returns (address);
function getPair(address tokenA, address tokenB) external view returns (address pair);
function allPairs(uint) external view returns (address pair);
function allPairsLength() external view returns (uint);
function createPair(address tokenA, address tokenB) external returns (address pair);
function setFeeTo(address) external;
function setFeeToSetter(address) external;
}
IUniswapV2Router01.sol 95 lines
pragma solidity >=0.6.2;
interface IUniswapV2Router01 {
function factory() external pure returns (address);
function WETH() external pure returns (address);
function addLiquidity(
address tokenA,
address tokenB,
uint amountADesired,
uint amountBDesired,
uint amountAMin,
uint amountBMin,
address to,
uint deadline
) external returns (uint amountA, uint amountB, uint liquidity);
function addLiquidityETH(
address token,
uint amountTokenDesired,
uint amountTokenMin,
uint amountETHMin,
address to,
uint deadline
) external payable returns (uint amountToken, uint amountETH, uint liquidity);
function removeLiquidity(
address tokenA,
address tokenB,
uint liquidity,
uint amountAMin,
uint amountBMin,
address to,
uint deadline
) external returns (uint amountA, uint amountB);
function removeLiquidityETH(
address token,
uint liquidity,
uint amountTokenMin,
uint amountETHMin,
address to,
uint deadline
) external returns (uint amountToken, uint amountETH);
function removeLiquidityWithPermit(
address tokenA,
address tokenB,
uint liquidity,
uint amountAMin,
uint amountBMin,
address to,
uint deadline,
bool approveMax, uint8 v, bytes32 r, bytes32 s
) external returns (uint amountA, uint amountB);
function removeLiquidityETHWithPermit(
address token,
uint liquidity,
uint amountTokenMin,
uint amountETHMin,
address to,
uint deadline,
bool approveMax, uint8 v, bytes32 r, bytes32 s
) external returns (uint amountToken, uint amountETH);
function swapExactTokensForTokens(
uint amountIn,
uint amountOutMin,
address[] calldata path,
address to,
uint deadline
) external returns (uint[] memory amounts);
function swapTokensForExactTokens(
uint amountOut,
uint amountInMax,
address[] calldata path,
address to,
uint deadline
) external returns (uint[] memory amounts);
function swapExactETHForTokens(uint amountOutMin, address[] calldata path, address to, uint deadline)
external
payable
returns (uint[] memory amounts);
function swapTokensForExactETH(uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline)
external
returns (uint[] memory amounts);
function swapExactTokensForETH(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline)
external
returns (uint[] memory amounts);
function swapETHForExactTokens(uint amountOut, address[] calldata path, address to, uint deadline)
external
payable
returns (uint[] memory amounts);
function quote(uint amountA, uint reserveA, uint reserveB) external pure returns (uint amountB);
function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) external pure returns (uint amountOut);
function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut) external pure returns (uint amountIn);
function getAmountsOut(uint amountIn, address[] calldata path) external view returns (uint[] memory amounts);
function getAmountsIn(uint amountOut, address[] calldata path) external view returns (uint[] memory amounts);
}
IUniswapV2Router02.sol 44 lines
pragma solidity >=0.6.2;
import './IUniswapV2Router01.sol';
interface IUniswapV2Router02 is IUniswapV2Router01 {
function removeLiquidityETHSupportingFeeOnTransferTokens(
address token,
uint liquidity,
uint amountTokenMin,
uint amountETHMin,
address to,
uint deadline
) external returns (uint amountETH);
function removeLiquidityETHWithPermitSupportingFeeOnTransferTokens(
address token,
uint liquidity,
uint amountTokenMin,
uint amountETHMin,
address to,
uint deadline,
bool approveMax, uint8 v, bytes32 r, bytes32 s
) external returns (uint amountETH);
function swapExactTokensForTokensSupportingFeeOnTransferTokens(
uint amountIn,
uint amountOutMin,
address[] calldata path,
address to,
uint deadline
) external;
function swapExactETHForTokensSupportingFeeOnTransferTokens(
uint amountOutMin,
address[] calldata path,
address to,
uint deadline
) external payable;
function swapExactTokensForETHSupportingFeeOnTransferTokens(
uint amountIn,
uint amountOutMin,
address[] calldata path,
address to,
uint deadline
) external;
}
Read Contract
DOMAIN_SEPARATOR 0x3644e515 → bytes32
TOTAL_SUPPLY 0x902d55a5 → uint256
allowance 0xdd62ed3e → uint256
balanceOf 0x70a08231 → uint256
boughtAmount 0x764a730a → uint256
buyFee 0x47062402 → uint256
decimals 0x313ce567 → uint8
getReceivers 0xe061646b → address[], uint256[]
isExcludedFromFee 0x5342acb4 → bool
isWhitelisted 0x3af32abf → bool
maxBuyAmount 0x88e765ff → uint256
name 0x06fdde03 → string
nonces 0x7ecebe00 → uint256
owner 0x8da5cb5b → address
pair 0xa8aa1b31 → address
receiversShares 0x10b21dcb → uint256
sellFee 0x2b14ca56 → uint256
symbol 0x95d89b41 → string
totalShares 0x3a98ef39 → uint256
totalSupply 0x18160ddd → uint256
tradingEnabled 0x4ada218b → bool
uniswapRouter 0x735de9f7 → address
Write Contract 15 functions
These functions modify contract state and require a wallet transaction to execute.
addReceiver 0x5f3ccdd9
address receiver
uint256 shares
approve 0x095ea7b3
address spender
uint256 amount
returns: bool
distributeShares 0x429e3846
No parameters
permit 0xd505accf
address owner
address spender
uint256 value
uint256 deadline
uint8 v
bytes32 r
bytes32 s
removeLimits 0x751039fc
No parameters
removeReceiver 0x6552d8b4
address receiver
setBuyFee 0x0cc835a3
uint256 _buyFee
setExcludedFromFee 0x6612e66f
address account
bool excluded
setMaxBuyAmount 0xf34eb0b8
uint256 _maxBuyAmount
setSellFee 0x8b4cee08
uint256 _sellFee
setWhitelisted 0x9281aa0b
address account
bool whitelisted
startTrading 0x293230b8
No parameters
transfer 0xa9059cbb
address to
uint256 amount
returns: bool
transferFrom 0x23b872dd
address from
address to
uint256 amount
returns: bool
transferOwnership 0xf2fde38b
address newOwner
Recent Transactions
No transactions found for this address