Verified Contract
0x0505a5Cf69376C633d2cA0D34Cc4d3B9f69cB09e
Pin to watchlist
scan to copy
zkLTC Balance
0
hard money native
Transactions
11
Token transfers
22
Validations
0
blocks produced
Hard Money Score
33
/100
TOKEN DOMINANT
share of activity in native zkLTC vs. tokens
native
11
tokens
22
Contract name
AMMPool
Compiler
v0.8.30+commit.73712a01
Optimization
enabled · 200 runs
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.30;
// ─── ERC20 Base ───────────────────────────────────────────────
abstract contract ERC20Base {
string public name;
string public symbol;
uint8 public decimals = 18;
uint256 public totalSupply;
mapping(address => uint256) public balanceOf;
mapping(address => mapping(address => uint256)) public allowance;
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) {
name = _name; symbol = _symbol;
}
function _mint(address to, uint256 amt) internal {
totalSupply += amt; balanceOf[to] += amt;
emit Transfer(address(0), to, amt);
}
function _burn(address from, uint256 amt) internal {
require(balanceOf[from] >= amt, "bal");
totalSupply -= amt; balanceOf[from] -= amt;
emit Transfer(from, address(0), amt);
}
function transfer(address to, uint256 amt) public returns (bool) {
require(balanceOf[msg.sender] >= amt, "bal");
balanceOf[msg.sender] -= amt; balanceOf[to] += amt;
emit Transfer(msg.sender, to, amt); return true;
}
function approve(address sp, uint256 amt) public returns (bool) {
allowance[msg.sender][sp] = amt;
emit Approval(msg.sender, sp, amt); return true;
}
function transferFrom(address from, address to, uint256 amt) public returns (bool) {
require(balanceOf[from] >= amt, "bal");
require(allowance[from][msg.sender] >= amt, "allow");
allowance[from][msg.sender] -= amt;
balanceOf[from] -= amt; balanceOf[to] += amt;
emit Transfer(from, to, amt); return true;
}
}
// ─── Megan Token ─────────────────────────────────────────────
contract MeganToken is ERC20Base {
address public owner;
constructor() ERC20Base("Megan", "MGN") {
owner = msg.sender;
_mint(msg.sender, 2_000_000 * 1e18);
}
function mint(address to, uint256 amt) external {
require(msg.sender == owner, "owner");
_mint(to, amt);
}
function burn(uint256 amt) external { _burn(msg.sender, amt); }
}
// ─── Lola Token ───────────────────────────────────────────────
contract LolaToken is ERC20Base {
address public owner;
constructor() ERC20Base("Lola", "LLA") {
owner = msg.sender;
_mint(msg.sender, 2_000_000 * 1e18);
}
function mint(address to, uint256 amt) external {
require(msg.sender == owner, "owner");
_mint(to, amt);
}
function burn(uint256 amt) external { _burn(msg.sender, amt); }
}
// ─── ERC721 Base ──────────────────────────────────────────────
abstract contract ERC721Base {
string public name;
string public symbol;
uint256 public totalSupply;
mapping(uint256 => address) public ownerOf;
mapping(address => uint256) public balanceOf;
mapping(uint256 => address) public getApproved;
mapping(address => mapping(address => bool)) public isApprovedForAll;
event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
constructor(string memory _name, string memory _symbol) {
name = _name; symbol = _symbol;
}
function _mint(address to) internal returns (uint256 id) {
id = ++totalSupply;
ownerOf[id] = to; balanceOf[to]++;
emit Transfer(address(0), to, id);
}
function approve(address to, uint256 id) public {
require(ownerOf[id] == msg.sender || isApprovedForAll[ownerOf[id]][msg.sender], "auth");
getApproved[id] = to;
emit Approval(ownerOf[id], to, id);
}
function setApprovalForAll(address op, bool approved) public {
isApprovedForAll[msg.sender][op] = approved;
emit ApprovalForAll(msg.sender, op, approved);
}
function transferFrom(address from, address to, uint256 id) public {
require(ownerOf[id] == from, "owner");
require(
msg.sender == from ||
msg.sender == getApproved[id] ||
isApprovedForAll[from][msg.sender],
"auth"
);
ownerOf[id] = to; balanceOf[from]--; balanceOf[to]++;
delete getApproved[id];
emit Transfer(from, to, id);
}
}
// ─── Georgia NFT ──────────────────────────────────────────────
contract GeorgiaNFT is ERC721Base {
address public owner;
mapping(uint256 => uint256) public nftPower;
mapping(address => uint256[]) private _owned;
constructor() ERC721Base("Georgia", "GEO") { owner = msg.sender; }
function mint(address to) external returns (uint256 id) {
require(msg.sender == owner, "owner");
id = _mint(to);
nftPower[id] = 100 + (id * 7) % 901;
_owned[to].push(id);
}
function tokensOf(address user) external view returns (uint256[] memory) {
return _owned[user];
}
function burn(uint256 id) external {
require(ownerOf[id] == msg.sender, "owner");
ownerOf[id] = address(0); balanceOf[msg.sender]--;
emit Transfer(msg.sender, address(0), id);
}
}
// ─── Tbilisi NFT ──────────────────────────────────────────────
contract TbilisiNFT is ERC721Base {
address public owner;
mapping(uint256 => uint256) public nftRarity;
mapping(address => uint256[]) private _owned;
constructor() ERC721Base("Tbilisi", "TBS") { owner = msg.sender; }
function mint(address to) external returns (uint256 id) {
require(msg.sender == owner, "owner");
id = _mint(to);
nftRarity[id] = (id % 3) + 1;
_owned[to].push(id);
}
function tokensOf(address user) external view returns (uint256[] memory) {
return _owned[user];
}
function burn(uint256 id) external {
require(ownerOf[id] == msg.sender, "owner");
ownerOf[id] = address(0); balanceOf[msg.sender]--;
emit Transfer(msg.sender, address(0), id);
}
}
// ─── Oracle ───────────────────────────────────────────────────
contract Oracle {
address public owner;
mapping(address => uint256) public price;
mapping(address => uint256) public updatedAt;
event PriceUpdated(address indexed token, uint256 newPrice);
constructor() { owner = msg.sender; }
function setPrice(address token, uint256 _price) external {
require(msg.sender == owner, "owner");
price[token] = _price;
updatedAt[token] = block.timestamp;
emit PriceUpdated(token, _price);
}
function getPrice(address token) external view returns (uint256) {
require(price[token] > 0, "no price");
return price[token];
}
}
// ─── AMM Pool ─────────────────────────────────────────────────
contract AMMPool {
address public tokenA;
address public tokenB;
uint256 public reserveA;
uint256 public reserveB;
uint256 public totalLP;
mapping(address => uint256) public lpBalance;
event LiquidityAdded(address indexed user, uint256 amtA, uint256 amtB, uint256 lp);
event LiquidityRemoved(address indexed user, uint256 amtA, uint256 amtB, uint256 lp);
event Swapped(address indexed user, address tokenIn, uint256 amtIn, uint256 amtOut);
constructor(address _a, address _b) { tokenA = _a; tokenB = _b; }
function addLiquidity(uint256 amtA, uint256 amtB) external returns (uint256 lp) {
require(amtA > 0 && amtB > 0, "zero");
ERC20Base(tokenA).transferFrom(msg.sender, address(this), amtA);
ERC20Base(tokenB).transferFrom(msg.sender, address(this), amtB);
if (totalLP == 0) {
lp = _sqrt(amtA * amtB);
} else {
uint256 lpA = (amtA * totalLP) / reserveA;
uint256 lpB = (amtB * totalLP) / reserveB;
lp = lpA < lpB ? lpA : lpB;
}
require(lp > 0, "lp=0");
reserveA += amtA; reserveB += amtB;
totalLP += lp; lpBalance[msg.sender] += lp;
emit LiquidityAdded(msg.sender, amtA, amtB, lp);
}
function removeLiquidity(uint256 lp) external returns (uint256 amtA, uint256 amtB) {
require(lpBalance[msg.sender] >= lp, "lp bal");
amtA = (lp * reserveA) / totalLP;
amtB = (lp * reserveB) / totalLP;
lpBalance[msg.sender] -= lp; totalLP -= lp;
reserveA -= amtA; reserveB -= amtB;
ERC20Base(tokenA).transfer(msg.sender, amtA);
ERC20Base(tokenB).transfer(msg.sender, amtB);
emit LiquidityRemoved(msg.sender, amtA, amtB, lp);
}
function swapAforB(uint256 amtIn) external returns (uint256 amtOut) {
require(amtIn > 0 && reserveA > 0 && reserveB > 0, "no liq");
ERC20Base(tokenA).transferFrom(msg.sender, address(this), amtIn);
uint256 fee = amtIn * 997;
amtOut = (fee * reserveB) / (reserveA * 1000 + fee);
reserveA += amtIn; reserveB -= amtOut;
ERC20Base(tokenB).transfer(msg.sender, amtOut);
emit Swapped(msg.sender, tokenA, amtIn, amtOut);
}
function swapBforA(uint256 amtIn) external returns (uint256 amtOut) {
require(amtIn > 0 && reserveA > 0 && reserveB > 0, "no liq");
ERC20Base(tokenB).transferFrom(msg.sender, address(this), amtIn);
uint256 fee = amtIn * 997;
amtOut = (fee * reserveA) / (reserveB * 1000 + fee);
reserveB += amtIn; reserveA -= amtOut;
ERC20Base(tokenA).transfer(msg.sender, amtOut);
emit Swapped(msg.sender, tokenB, amtIn, amtOut);
}
function _sqrt(uint256 x) internal pure returns (uint256 y) {
if (x == 0) return 0;
uint256 z = (x + 1) / 2; y = x;
while (z < y) { y = z; z = (x / z + z) / 2; }
}
}
// ─── NFT Staking ──────────────────────────────────────────────
contract NFTStaking {
address public rewardToken;
address public georgiaNFT;
address public tbilisiNFT;
uint256 public rewardPerBlock = 1e16;
struct Stake { uint256 tokenId; address nftContract; uint256 stakedAt; }
mapping(address => Stake[]) public stakes;
event NFTStaked(address indexed user, address nft, uint256 id);
event NFTUnstaked(address indexed user, address nft, uint256 id, uint256 reward);
event RewardClaimed(address indexed user, uint256 reward);
constructor(address _reward, address _geo, address _tbs) {
rewardToken = _reward; georgiaNFT = _geo; tbilisiNFT = _tbs;
}
function stakeNFT(address nftContract, uint256 tokenId) external {
require(nftContract == georgiaNFT || nftContract == tbilisiNFT, "unsupported");
ERC721Base(nftContract).transferFrom(msg.sender, address(this), tokenId);
stakes[msg.sender].push(Stake(tokenId, nftContract, block.number));
emit NFTStaked(msg.sender, nftContract, tokenId);
}
function unstakeNFT(uint256 idx) external {
Stake[] storage s = stakes[msg.sender];
require(idx < s.length, "idx");
Stake memory st = s[idx];
uint256 reward = (block.number - st.stakedAt) * rewardPerBlock;
s[idx] = s[s.length - 1]; s.pop();
ERC721Base(st.nftContract).transferFrom(address(this), msg.sender, st.tokenId);
if (reward > 0 && ERC20Base(rewardToken).balanceOf(address(this)) >= reward)
ERC20Base(rewardToken).transfer(msg.sender, reward);
emit NFTUnstaked(msg.sender, st.nftContract, st.tokenId, reward);
}
function claimReward(uint256 idx) external {
Stake[] storage s = stakes[msg.sender];
require(idx < s.length, "idx");
uint256 reward = (block.number - s[idx].stakedAt) * rewardPerBlock;
s[idx].stakedAt = block.number;
if (reward > 0 && ERC20Base(rewardToken).balanceOf(address(this)) >= reward)
ERC20Base(rewardToken).transfer(msg.sender, reward);
emit RewardClaimed(msg.sender, reward);
}
function pendingReward(address user, uint256 idx) external view returns (uint256) {
Stake[] storage s = stakes[user];
if (idx >= s.length) return 0;
return (block.number - s[idx].stakedAt) * rewardPerBlock;
}
function stakeCount(address user) external view returns (uint256) {
return stakes[user].length;
}
}
// ─── Token Staking ────────────────────────────────────────────
contract TokenStaking {
address public stakingToken;
address public rewardToken;
uint256 public rewardRate = 100;
struct Info { uint256 amount; uint256 lastBlock; }
mapping(address => Info) public stakers;
uint256 public totalStaked;
event Staked(address indexed user, uint256 amt);
event Unstaked(address indexed user, uint256 amt);
event RewardClaimed(address indexed user, uint256 amt);
constructor(address _staking, address _reward) {
stakingToken = _staking; rewardToken = _reward;
}
function stake(uint256 amt) external {
require(amt > 0, "zero");
_claim(msg.sender);
ERC20Base(stakingToken).transferFrom(msg.sender, address(this), amt);
stakers[msg.sender].amount += amt; totalStaked += amt;
stakers[msg.sender].lastBlock = block.number;
emit Staked(msg.sender, amt);
}
function unstake(uint256 amt) external {
require(stakers[msg.sender].amount >= amt, "amt");
_claim(msg.sender);
stakers[msg.sender].amount -= amt; totalStaked -= amt;
ERC20Base(stakingToken).transfer(msg.sender, amt);
emit Unstaked(msg.sender, amt);
}
function claimReward() external {
uint256 r = _claim(msg.sender);
require(r > 0, "no reward");
emit RewardClaimed(msg.sender, r);
}
function pending(address user) public view returns (uint256) {
Info storage i = stakers[user];
if (i.amount == 0) return 0;
return (i.amount * (block.number - i.lastBlock) * rewardRate) / 1e24;
}
function _claim(address user) internal returns (uint256 r) {
r = pending(user);
if (r > 0 && ERC20Base(rewardToken).balanceOf(address(this)) >= r)
ERC20Base(rewardToken).transfer(user, r);
stakers[user].lastBlock = block.number;
}
}