编译器
0.8.10+commit.fc410830
文件 1 的 7:Context.sol
pragma solidity ^0.8.0;
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}
文件 2 的 7:ILiquidityPoolImplementation.sol
pragma solidity =0.8.10;
enum SpecifiedToken {
X,
Y
}
interface ILiquidityPoolImplementation {
function swapGivenInputAmount(
uint256 xBalance,
uint256 yBalance,
uint256 inputAmount,
SpecifiedToken inputToken
) external view returns (uint256 outputAmount);
function depositGivenInputAmount(
uint256 xBalance,
uint256 yBalance,
uint256 totalSupply,
uint256 depositedAmount,
SpecifiedToken depositedToken
) external view returns (uint256 mintedAmount);
function withdrawGivenInputAmount(
uint256 xBalance,
uint256 yBalance,
uint256 totalSupply,
uint256 burnedAmount,
SpecifiedToken withdrawnToken
) external view returns (uint256 withdrawnAmount);
function swapGivenOutputAmount(
uint256 xBalance,
uint256 yBalance,
uint256 outputAmount,
SpecifiedToken outputToken
) external view returns (uint256 inputAmount);
function depositGivenOutputAmount(
uint256 xBalance,
uint256 yBalance,
uint256 totalSupply,
uint256 mintedAmount,
SpecifiedToken depositedToken
) external view returns (uint256 depositedAmount);
function withdrawGivenOutputAmount(
uint256 xBalance,
uint256 yBalance,
uint256 totalSupply,
uint256 withdrawnAmount,
SpecifiedToken withdrawnToken
) external view returns (uint256 burnedAmount);
}
文件 3 的 7:IOceanPrimitive.sol
pragma solidity =0.8.10;
interface IOceanPrimitive {
function computeOutputAmount(
uint256 inputToken,
uint256 outputToken,
uint256 inputAmount,
address userAddress,
bytes32 metadata
) external returns (uint256 outputAmount);
function computeInputAmount(
uint256 inputToken,
uint256 outputToken,
uint256 outputAmount,
address userAddress,
bytes32 metadata
) external returns (uint256 inputAmount);
function getTokenSupply(uint256 tokenId)
external
view
returns (uint256 totalSupply);
}
文件 4 的 7:IOceanToken.sol
pragma solidity =0.8.10;
interface IOceanToken {
function registerNewTokens(
uint256 currentNumberOfTokens,
uint256 numberOfAdditionalTokens
) external returns (uint256[] memory);
}
文件 5 的 7:LiquidityPool.sol
pragma solidity =0.8.10;
import "../ocean/IOceanPrimitive.sol";
import "../ocean/IOceanToken.sol";
interface IERC1155 {
function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids)
external
view
returns (uint256[] memory);
}
enum ComputeType {
Deposit,
Swap,
Withdraw
}
abstract contract LiquidityPool is IOceanPrimitive {
address public immutable ocean;
uint256 public immutable xToken;
uint256 public immutable yToken;
uint256 public immutable lpTokenId;
address private immutable claimerOrDeployer;
uint256 private immutable initialLpTokenSupply;
uint256 private constant UNCLAIMED = 2;
uint256 private constant HALF_CLAIMED = 1;
uint256 private constant CLAIMED = 0;
uint256 private initialSupplyClaimed = UNCLAIMED;
uint256 private lpTokenSupply = 0;
event Swap(
uint256 inputToken,
uint256 inputAmount,
uint256 outputAmount,
bytes32 slippageProtection,
address user,
bool computeOutput
);
event Deposit(
uint256 inputToken,
uint256 inputAmount,
uint256 outputAmount,
bytes32 slippageProtection,
address user,
bool computeOutput
);
event Withdraw(
uint256 outputToken,
uint256 inputAmount,
uint256 outputAmount,
bytes32 slippageProtection,
address user,
bool computeOutput
);
event InitialLiquidity(
uint256 inputToken,
uint256 inputAmount,
uint256 outputAmount,
address user,
bool active
);
constructor(
uint256 xToken_,
uint256 yToken_,
address ocean_,
uint256 initialLpTokenSupply_,
address claimer
) {
claimerOrDeployer = claimer == address(0) ? msg.sender : claimer;
initialLpTokenSupply = initialLpTokenSupply_;
ocean = ocean_;
xToken = xToken_;
yToken = yToken_;
uint256[] memory registeredToken = IOceanToken(ocean_)
.registerNewTokens(0, 1);
lpTokenId = registeredToken[0];
}
modifier onlyOcean() {
require(msg.sender == ocean);
_;
}
modifier onlyClaimed() {
require(initialSupplyClaimed == CLAIMED);
_;
}
function computeOutputAmount(
uint256 inputToken,
uint256 outputToken,
uint256 inputAmount,
address userAddress,
bytes32 minimumOutputAmount
) external override onlyOcean returns (uint256 outputAmount) {
ComputeType action = _determineComputeType(inputToken, outputToken);
if (initialSupplyClaimed != CLAIMED) {
outputAmount = _handleInitialMints(
inputToken,
inputAmount,
userAddress,
action
);
lpTokenSupply += outputAmount;
emit InitialLiquidity(
inputToken,
inputAmount,
outputAmount,
userAddress,
(initialSupplyClaimed == CLAIMED)
);
} else if (action == ComputeType.Swap) {
outputAmount = swapGivenInputAmount(inputToken, inputAmount);
emit Swap(
inputToken,
inputAmount,
outputAmount,
minimumOutputAmount,
userAddress,
true
);
} else if (action == ComputeType.Deposit) {
outputAmount = depositGivenInputAmount(inputToken, inputAmount);
lpTokenSupply += outputAmount;
emit Deposit(
inputToken,
inputAmount,
outputAmount,
minimumOutputAmount,
userAddress,
true
);
} else {
assert(action == ComputeType.Withdraw);
outputAmount = withdrawGivenInputAmount(outputToken, inputAmount);
lpTokenSupply -= inputAmount;
emit Withdraw(
outputToken,
inputAmount,
outputAmount,
minimumOutputAmount,
userAddress,
true
);
}
require(
uint256(minimumOutputAmount) <= outputAmount,
"Slippage limit exceeded"
);
}
function computeInputAmount(
uint256 inputToken,
uint256 outputToken,
uint256 outputAmount,
address userAddress,
bytes32 maximumInputAmount
) external override onlyOcean onlyClaimed returns (uint256 inputAmount) {
ComputeType action = _determineComputeType(inputToken, outputToken);
if (action == ComputeType.Swap) {
inputAmount = swapGivenOutputAmount(outputToken, outputAmount);
emit Swap(
inputToken,
inputAmount,
outputAmount,
maximumInputAmount,
userAddress,
false
);
} else if (action == ComputeType.Deposit) {
inputAmount = depositGivenOutputAmount(inputToken, outputAmount);
lpTokenSupply += outputAmount;
emit Deposit(
inputToken,
inputAmount,
outputAmount,
maximumInputAmount,
userAddress,
false
);
} else {
assert(action == ComputeType.Withdraw);
inputAmount = withdrawGivenOutputAmount(outputToken, outputAmount);
lpTokenSupply -= inputAmount;
emit Withdraw(
outputToken,
inputAmount,
outputAmount,
maximumInputAmount,
userAddress,
false
);
}
if (uint256(maximumInputAmount) > 0) {
require(
uint256(maximumInputAmount) >= inputAmount,
"Slippage limit exceeded"
);
}
}
function getTokenSupply(uint256 tokenId)
external
view
override
returns (uint256 totalSupply)
{
require(tokenId == lpTokenId, "invalid tokenId");
totalSupply = lpTokenSupply;
}
function swapGivenInputAmount(uint256 inputToken, uint256 inputAmount)
public
view
virtual
returns (uint256 outputAmount);
function depositGivenInputAmount(
uint256 depositToken,
uint256 depositAmount
) public view virtual returns (uint256 mintAmount);
function withdrawGivenInputAmount(
uint256 withdrawnToken,
uint256 burnAmount
) public view virtual returns (uint256 withdrawnAmount);
function swapGivenOutputAmount(uint256 outputToken, uint256 outputAmount)
public
view
virtual
returns (uint256 inputAmount);
function depositGivenOutputAmount(uint256 depositToken, uint256 mintAmount)
public
view
virtual
returns (uint256 depositAmount);
function withdrawGivenOutputAmount(
uint256 withdrawnToken,
uint256 withdrawnAmount
) public view virtual returns (uint256 burnAmount);
function _getBalances()
internal
view
returns (uint256 xBalance, uint256 yBalance)
{
address[] memory accounts = new address[](2);
uint256[] memory ids = new uint256[](2);
accounts[0] = accounts[1] = address(this);
ids[0] = xToken;
ids[1] = yToken;
uint256[] memory result = IERC1155(ocean).balanceOfBatch(accounts, ids);
(xBalance, yBalance) = (result[0], result[1]);
}
function _getTotalSupply() internal view returns (uint256 totalSupply) {
totalSupply = lpTokenSupply;
}
function _handleInitialMints(
uint256 inputToken,
uint256 inputAmount,
address userAddress,
ComputeType action
) private returns (uint256 outputAmount) {
require(userAddress == claimerOrDeployer);
require(action == ComputeType.Deposit);
require(inputAmount >= 10**12);
assert(initialSupplyClaimed != CLAIMED);
(uint256 xBalance, uint256 yBalance) = _getBalances();
if (initialSupplyClaimed == UNCLAIMED) {
assert(_getTotalSupply() == 0);
assert((xBalance == 0) && (yBalance == 0));
outputAmount = initialLpTokenSupply / 2;
initialSupplyClaimed = HALF_CLAIMED;
} else if ((initialSupplyClaimed == HALF_CLAIMED) && (xBalance == 0)) {
assert(_getTotalSupply() == initialLpTokenSupply / 2);
assert(yBalance > 0);
require(inputToken == xToken);
outputAmount = initialLpTokenSupply / 2;
initialSupplyClaimed = CLAIMED;
} else {
assert(
(initialSupplyClaimed == HALF_CLAIMED) &&
(yBalance == 0) &&
(_getTotalSupply() == initialLpTokenSupply / 2)
);
require(inputToken == yToken);
outputAmount = initialLpTokenSupply / 2;
initialSupplyClaimed = CLAIMED;
}
}
function _determineComputeType(uint256 inputToken, uint256 outputToken)
private
view
returns (ComputeType computeType)
{
if (
((inputToken == xToken) && (outputToken == yToken)) ||
((inputToken == yToken) && (outputToken == xToken))
) {
return ComputeType.Swap;
} else if (
((inputToken == xToken) || (inputToken == yToken)) &&
(outputToken == lpTokenId)
) {
return ComputeType.Deposit;
} else if (
(inputToken == lpTokenId) &&
((outputToken == xToken) || (outputToken == yToken))
) {
return ComputeType.Withdraw;
} else {
revert("Invalid ComputeType");
}
}
}
文件 6 的 7:LiquidityPoolProxy.sol
pragma solidity =0.8.10;
import "@openzeppelin/contracts/access/Ownable.sol";
import {LiquidityPool} from "./LiquidityPool.sol";
import {ILiquidityPoolImplementation, SpecifiedToken} from "./ILiquidityPoolImplementation.sol";
contract LiquidityPoolProxy is LiquidityPool, Ownable {
ILiquidityPoolImplementation public implementation;
bool public poolFrozen = false;
event ImplementationChanged(
address operator,
address oldImplementation,
address newImplementation
);
event PoolFrozen(
address operator
);
modifier notFrozen() {
require(poolFrozen == false, "Pool is frozen");
_;
}
constructor(
uint256 xToken_,
uint256 yToken_,
address ocean_,
uint256 initialLpTokenSupply_
)
LiquidityPool(
xToken_,
yToken_,
ocean_,
initialLpTokenSupply_,
address(0)
)
{
assert(uint8(SpecifiedToken.X) == 0);
assert(uint8(SpecifiedToken.Y) == 1);
}
function setImplementation(address _implementation) external onlyOwner {
emit ImplementationChanged(
msg.sender,
address(implementation),
_implementation
);
implementation = ILiquidityPoolImplementation(_implementation);
}
function freezePool(bool freeze) external onlyOwner {
emit PoolFrozen(msg.sender);
poolFrozen = freeze;
}
function swapGivenInputAmount(
uint256 inputToken,
uint256 inputAmount)
public view override notFrozen returns (uint256 outputAmount) {
(uint256 xBalance, uint256 yBalance) = _getBalances();
outputAmount = implementation.swapGivenInputAmount(
xBalance,
yBalance,
inputAmount,
_specifiedToken(inputToken)
);
}
function depositGivenInputAmount(
uint256 depositToken,
uint256 depositAmount
) public view override notFrozen returns (uint256 mintAmount) {
(uint256 xBalance, uint256 yBalance) = _getBalances();
uint256 totalSupply = _getTotalSupply();
mintAmount = implementation.depositGivenInputAmount(
xBalance,
yBalance,
totalSupply,
depositAmount,
_specifiedToken(depositToken)
);
}
function withdrawGivenInputAmount(
uint256 withdrawnToken,
uint256 burnAmount
) public view override notFrozen returns (uint256 withdrawnAmount) {
(uint256 xBalance, uint256 yBalance) = _getBalances();
uint256 totalSupply = _getTotalSupply();
withdrawnAmount = implementation.withdrawGivenInputAmount(
xBalance,
yBalance,
totalSupply,
burnAmount,
_specifiedToken(withdrawnToken)
);
}
function swapGivenOutputAmount(
uint256 outputToken,
uint256 outputAmount
) public view override notFrozen returns (uint256 inputAmount) {
(uint256 xBalance, uint256 yBalance) = _getBalances();
inputAmount = implementation.swapGivenOutputAmount(
xBalance,
yBalance,
outputAmount,
_specifiedToken(outputToken)
);
}
function depositGivenOutputAmount(
uint256 depositToken,
uint256 mintAmount
) public view override notFrozen returns (uint256 depositAmount)
{
(uint256 xBalance, uint256 yBalance) = _getBalances();
uint256 totalSupply = _getTotalSupply();
depositAmount = implementation.depositGivenOutputAmount(
xBalance,
yBalance,
totalSupply,
mintAmount,
_specifiedToken(depositToken)
);
}
function withdrawGivenOutputAmount(
uint256 withdrawnToken,
uint256 withdrawnAmount
) public view override notFrozen returns (uint256 burnAmount) {
(uint256 xBalance, uint256 yBalance) = _getBalances();
uint256 totalSupply = _getTotalSupply();
burnAmount = implementation.withdrawGivenOutputAmount(
xBalance,
yBalance,
totalSupply,
withdrawnAmount,
_specifiedToken(withdrawnToken)
);
}
function _specifiedToken(uint256 tokenId)
private
view
returns (SpecifiedToken)
{
if (tokenId == xToken) {
return SpecifiedToken.X;
} else {
assert(tokenId == yToken);
return SpecifiedToken.Y;
}
}
}
文件 7 的 7:Ownable.sol
pragma solidity ^0.8.0;
import "../utils/Context.sol";
abstract contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
constructor() {
_transferOwnership(_msgSender());
}
modifier onlyOwner() {
_checkOwner();
_;
}
function owner() public view virtual returns (address) {
return _owner;
}
function _checkOwner() internal view virtual {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
}
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
_transferOwnership(newOwner);
}
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
{
"compilationTarget": {
"src/proteus/LiquidityPoolProxy.sol": "LiquidityPoolProxy"
},
"evmVersion": "london",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 10000000
},
"remappings": []
}
[{"inputs":[{"internalType":"uint256","name":"xToken_","type":"uint256"},{"internalType":"uint256","name":"yToken_","type":"uint256"},{"internalType":"address","name":"ocean_","type":"address"},{"internalType":"uint256","name":"initialLpTokenSupply_","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"inputToken","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"inputAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"outputAmount","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"slippageProtection","type":"bytes32"},{"indexed":false,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"bool","name":"computeOutput","type":"bool"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"address","name":"oldImplementation","type":"address"},{"indexed":false,"internalType":"address","name":"newImplementation","type":"address"}],"name":"ImplementationChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"inputToken","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"inputAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"outputAmount","type":"uint256"},{"indexed":false,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"bool","name":"active","type":"bool"}],"name":"InitialLiquidity","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"operator","type":"address"}],"name":"PoolFrozen","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"inputToken","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"inputAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"outputAmount","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"slippageProtection","type":"bytes32"},{"indexed":false,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"bool","name":"computeOutput","type":"bool"}],"name":"Swap","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"outputToken","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"inputAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"outputAmount","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"slippageProtection","type":"bytes32"},{"indexed":false,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"bool","name":"computeOutput","type":"bool"}],"name":"Withdraw","type":"event"},{"inputs":[{"internalType":"uint256","name":"inputToken","type":"uint256"},{"internalType":"uint256","name":"outputToken","type":"uint256"},{"internalType":"uint256","name":"outputAmount","type":"uint256"},{"internalType":"address","name":"userAddress","type":"address"},{"internalType":"bytes32","name":"maximumInputAmount","type":"bytes32"}],"name":"computeInputAmount","outputs":[{"internalType":"uint256","name":"inputAmount","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"inputToken","type":"uint256"},{"internalType":"uint256","name":"outputToken","type":"uint256"},{"internalType":"uint256","name":"inputAmount","type":"uint256"},{"internalType":"address","name":"userAddress","type":"address"},{"internalType":"bytes32","name":"minimumOutputAmount","type":"bytes32"}],"name":"computeOutputAmount","outputs":[{"internalType":"uint256","name":"outputAmount","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"depositToken","type":"uint256"},{"internalType":"uint256","name":"depositAmount","type":"uint256"}],"name":"depositGivenInputAmount","outputs":[{"internalType":"uint256","name":"mintAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"depositToken","type":"uint256"},{"internalType":"uint256","name":"mintAmount","type":"uint256"}],"name":"depositGivenOutputAmount","outputs":[{"internalType":"uint256","name":"depositAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"freeze","type":"bool"}],"name":"freezePool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getTokenSupply","outputs":[{"internalType":"uint256","name":"totalSupply","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"implementation","outputs":[{"internalType":"contract ILiquidityPoolImplementation","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lpTokenId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ocean","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"poolFrozen","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_implementation","type":"address"}],"name":"setImplementation","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"inputToken","type":"uint256"},{"internalType":"uint256","name":"inputAmount","type":"uint256"}],"name":"swapGivenInputAmount","outputs":[{"internalType":"uint256","name":"outputAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"outputToken","type":"uint256"},{"internalType":"uint256","name":"outputAmount","type":"uint256"}],"name":"swapGivenOutputAmount","outputs":[{"internalType":"uint256","name":"inputAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"withdrawnToken","type":"uint256"},{"internalType":"uint256","name":"burnAmount","type":"uint256"}],"name":"withdrawGivenInputAmount","outputs":[{"internalType":"uint256","name":"withdrawnAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"withdrawnToken","type":"uint256"},{"internalType":"uint256","name":"withdrawnAmount","type":"uint256"}],"name":"withdrawGivenOutputAmount","outputs":[{"internalType":"uint256","name":"burnAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"xToken","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"yToken","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]