Skip to content

Instantly share code, notes, and snippets.

@OxMarco
Created December 14, 2024 12:20
Show Gist options
  • Save OxMarco/8bb8b4bdbcd0d4b8e4462fc65dbe9bc3 to your computer and use it in GitHub Desktop.
Save OxMarco/8bb8b4bdbcd0d4b8e4462fc65dbe9bc3 to your computer and use it in GitHub Desktop.
Token and swap router
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.25;
import {ERC20, ERC20Permit} from "@openzeppelin/contracts/token/ERC20/extensions/ERC20Permit.sol";
import {ERC20Burnable} from "@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol";
contract Token is ERC20Permit, ERC20Burnable {
string public image;
constructor(string memory _name, string memory _symbol, string memory _image, uint256 _totalSupply)
ERC20Permit(_name) ERC20(_name, _symbol) {
image = _image;
_mint(msg.sender, _totalSupply);
}
function getImage() external view returns (string memory) {
return image;
}
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.25;
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
import {Token} from "./Token.sol";
contract Router is Ownable {
address public immutable uniRouter;
mapping(address token => address bondingCurve) public bondingCurves;
mapping(address token => address pool) public pools;
uint256 public threshold;
event ThresholdUpdated(uint256 previousThreshold, uint256 newThreshold, address indexed user);
event NewPoolDeployed(address indexed token, address indexed pool, address indexed user);
event NewBondingCurveCreated(address indexed token, address indexed bondingCurve, address indexed user);
event NewTokenDeployed(address token, string indexed name, string indexed symbol, string image, uint256 amount, address indexed user);
error UnsupportedToken();
constructor() Ownable(msg.sender) {}
function setThreshold(uint256 _threshold) external onlyOwner {
emit ThresholdUpdated(threshold, _threshold, msg.sender);
threshold = _threshold;
}
/// @dev allow deploying copycat tokens?
function deployToken(string memory name, string memory symbol, string memory image, uint256 amount) external {
require(bytes(name).length > 0 && bytes(symbol).length > 0 && bytes(image).length > 0, "Invalid token metadata");
require(amount > 0, "Amount must be greater than zero");
address token = address(new Token(name, symbol, image, amount));
address bondingCurve = address(new BondingCurve(token));
bondingCurves[token] = bondingCurve;
IERC20(token).approve(address(bondingCurve), type(uint256).max);
emit NewTokenDeployed(token, name, symbol, image, amount, msg.sender);
emit NewBondingCurveCreated(token, bondingCurve, msg.sender);
}
function buy(address token, uint256 amount) external {
// 0. check if the token has got a bonding curve, if not it was not launched through
// the platform
if(bondingCurves[token] == address(0)) revert UnsupportedToken();
// 1. check if a pool exists, if so swap on the pool
address poolAddress = pools[token];
if (poolAddress != address(0)) {
IPool(poolAddress).swapExactTokensForTokens();
}
IBondingCurve bondingCurve = IBondingCurve(bondingCurves[token]);
// 2. check if the bonding curve has surpassed the "graduation" threshold
// if so, deploy the pool
/// @dev gas stamping, this may turn out to be too expensive
if(bondingCurve.totalLiquidity() >= threshold) {
Pool pool = new Pool(token);
poolAddress = address(pool);
pools[token] = poolAddress;
IERC20(token).approve(poolAddress, type(uint256).max);
_migrateLiquidity(poolAddress);
emit NewPoolDeployed(token, poolAddress, msg.sender);
}
// 3. swap on the bonding curve
bondingCurve.swap(amount);
}
/// @dev tbd
function _migrateLiquidity(address pool) internal {
/*uniV2router.addLiquidity{value: address(this).balance}(
address(uniV2router), 0, address(pool));
*/
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment