¡El código fuente de este contrato está verificado!
Metadatos del Contrato
Compilador
0.6.12+commit.27d51765
Idioma
Solidity
Código Fuente del Contrato
Archivo 1 de 11: BConst.sol
// SPDX-License-Identifier: GPL-3.0// This program is free software: you can redistribute it and/or modify// it under the terms of the GNU General Public License as published by// the Free Software Foundation, either version 3 of the License, or// (at your option) any later version.// This program is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the// GNU General Public License for more details.// You should have received a copy of the GNU General Public License// along with this program. If not, see <http://www.gnu.org/licenses/>.pragmasolidity 0.6.12;contractBConst{
uintpublicconstant BONE =10**18;
uintpublicconstant MIN_BOUND_TOKENS =2;
uintpublicconstant MAX_BOUND_TOKENS =9;
uintpublicconstant MIN_FEE = BONE /10**6;
uintpublicconstant MAX_FEE = BONE /10;
uintpublicconstant MIN_WEIGHT =1000000000;
uintpublicconstant MAX_WEIGHT = BONE *50;
uintpublicconstant MAX_TOTAL_WEIGHT = BONE *50;
uintpublicconstant MIN_BALANCE = BONE /10**12;
uintpublicconstant INIT_POOL_SUPPLY = BONE *100;
uintpublicconstant MIN_BPOW_BASE =1wei;
uintpublicconstant MAX_BPOW_BASE = (2* BONE) -1wei;
uintpublicconstant BPOW_PRECISION = BONE /10**10;
uintpublicconstant MAX_IN_RATIO = BONE /2;
uintpublicconstant MAX_OUT_RATIO = (BONE /3) +1wei;
}
Código Fuente del Contrato
Archivo 2 de 11: BMath.sol
// SPDX-License-Identifier: GPL-3.0// This program is free software: you can redistribute it and/or modify// it under the terms of the GNU General Public License as published by// the Free Software Foundation, either version 3 of the License, or// (at your option) any later version.// This program is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the// GNU General Public License for more details.// You should have received a copy of the GNU General Public License// along with this program. If not, see <http://www.gnu.org/licenses/>.pragmasolidity 0.6.12;import"./BNum.sol";
import"../interfaces/BMathInterface.sol";
contractBMathisBConst, BNum, BMathInterface{
/**********************************************************************************************
// calcSpotPrice //
// sP = spotPrice //
// bI = tokenBalanceIn ( bI / wI ) 1 //
// bO = tokenBalanceOut sP = ----------- * ---------- //
// wI = tokenWeightIn ( bO / wO ) ( 1 - sF ) //
// wO = tokenWeightOut //
// sF = swapFee //
**********************************************************************************************/functioncalcSpotPrice(uint tokenBalanceIn,
uint tokenWeightIn,
uint tokenBalanceOut,
uint tokenWeightOut,
uint swapFee
)
publicpurereturns (uint spotPrice)
{
uint numer = bdiv(tokenBalanceIn, tokenWeightIn);
uint denom = bdiv(tokenBalanceOut, tokenWeightOut);
uint ratio = bdiv(numer, denom);
uint scale = bdiv(BONE, bsub(BONE, swapFee));
return (spotPrice = bmul(ratio, scale));
}
/**********************************************************************************************
// calcOutGivenIn //
// aO = tokenAmountOut //
// bO = tokenBalanceOut //
// bI = tokenBalanceIn / / bI \ (wI / wO) \ //
// aI = tokenAmountIn aO = bO * | 1 - | -------------------------- | ^ | //
// wI = tokenWeightIn \ \ ( bI + ( aI * ( 1 - sF )) / / //
// wO = tokenWeightOut //
// sF = swapFee //
**********************************************************************************************/functioncalcOutGivenIn(uint tokenBalanceIn,
uint tokenWeightIn,
uint tokenBalanceOut,
uint tokenWeightOut,
uint tokenAmountIn,
uint swapFee
)
publicpurereturns (uint tokenAmountOut)
{
uint weightRatio = bdiv(tokenWeightIn, tokenWeightOut);
uint adjustedIn = bsub(BONE, swapFee);
adjustedIn = bmul(tokenAmountIn, adjustedIn);
uint y = bdiv(tokenBalanceIn, badd(tokenBalanceIn, adjustedIn));
uint foo = bpow(y, weightRatio);
uint bar = bsub(BONE, foo);
tokenAmountOut = bmul(tokenBalanceOut, bar);
return tokenAmountOut;
}
/**********************************************************************************************
// calcInGivenOut //
// aI = tokenAmountIn //
// bO = tokenBalanceOut / / bO \ (wO / wI) \ //
// bI = tokenBalanceIn bI * | | ------------ | ^ - 1 | //
// aO = tokenAmountOut aI = \ \ ( bO - aO ) / / //
// wI = tokenWeightIn -------------------------------------------- //
// wO = tokenWeightOut ( 1 - sF ) //
// sF = swapFee //
**********************************************************************************************/functioncalcInGivenOut(uint tokenBalanceIn,
uint tokenWeightIn,
uint tokenBalanceOut,
uint tokenWeightOut,
uint tokenAmountOut,
uint swapFee
)
publicpureoverridereturns (uint tokenAmountIn)
{
uint weightRatio = bdiv(tokenWeightOut, tokenWeightIn);
uint diff = bsub(tokenBalanceOut, tokenAmountOut);
uint y = bdiv(tokenBalanceOut, diff);
uint foo = bpow(y, weightRatio);
foo = bsub(foo, BONE);
tokenAmountIn = bsub(BONE, swapFee);
tokenAmountIn = bdiv(bmul(tokenBalanceIn, foo), tokenAmountIn);
return tokenAmountIn;
}
/**********************************************************************************************
// calcPoolOutGivenSingleIn //
// pAo = poolAmountOut / \ //
// tAi = tokenAmountIn /// / // wI \ \\ \ wI \ //
// wI = tokenWeightIn //| tAi *| 1 - || 1 - -- | * sF || + tBi \ -- \ //
// tW = totalWeight pAo=|| \ \ \\ tW / // | ^ tW | * pS - pS //
// tBi = tokenBalanceIn \\ ------------------------------------- / / //
// pS = poolSupply \\ tBi / / //
// sF = swapFee \ / //
**********************************************************************************************/functioncalcPoolOutGivenSingleIn(uint tokenBalanceIn,
uint tokenWeightIn,
uint poolSupply,
uint totalWeight,
uint tokenAmountIn,
uint swapFee
)
publicpurereturns (uint poolAmountOut)
{
// Charge the trading fee for the proportion of tokenAi/// which is implicitly traded to the other pool tokens.// That proportion is (1- weightTokenIn)// tokenAiAfterFee = tAi * (1 - (1-weightTi) * poolFee);uint normalizedWeight = bdiv(tokenWeightIn, totalWeight);
uint zaz = bmul(bsub(BONE, normalizedWeight), swapFee);
uint tokenAmountInAfterFee = bmul(tokenAmountIn, bsub(BONE, zaz));
uint newTokenBalanceIn = badd(tokenBalanceIn, tokenAmountInAfterFee);
uint tokenInRatio = bdiv(newTokenBalanceIn, tokenBalanceIn);
// uint newPoolSupply = (ratioTi ^ weightTi) * poolSupply;uint poolRatio = bpow(tokenInRatio, normalizedWeight);
uint newPoolSupply = bmul(poolRatio, poolSupply);
poolAmountOut = bsub(newPoolSupply, poolSupply);
return poolAmountOut;
}
/**********************************************************************************************
// calcSingleInGivenPoolOut //
// tAi = tokenAmountIn //(pS + pAo)\ / 1 \\ //
// pS = poolSupply || --------- | ^ | --------- || * bI - bI //
// pAo = poolAmountOut \\ pS / \(wI / tW)// //
// bI = balanceIn tAi = -------------------------------------------- //
// wI = weightIn / wI \ //
// tW = totalWeight | 1 - ---- | * sF //
// sF = swapFee \ tW / //
**********************************************************************************************/functioncalcSingleInGivenPoolOut(uint tokenBalanceIn,
uint tokenWeightIn,
uint poolSupply,
uint totalWeight,
uint poolAmountOut,
uint swapFee
)
publicpurereturns (uint tokenAmountIn)
{
uint normalizedWeight = bdiv(tokenWeightIn, totalWeight);
uint newPoolSupply = badd(poolSupply, poolAmountOut);
uint poolRatio = bdiv(newPoolSupply, poolSupply);
//uint newBalTi = poolRatio^(1/weightTi) * balTi;uint boo = bdiv(BONE, normalizedWeight);
uint tokenInRatio = bpow(poolRatio, boo);
uint newTokenBalanceIn = bmul(tokenInRatio, tokenBalanceIn);
uint tokenAmountInAfterFee = bsub(newTokenBalanceIn, tokenBalanceIn);
// Do reverse order of fees charged in joinswap_ExternAmountIn, this way// ``` pAo == joinswap_ExternAmountIn(Ti, joinswap_PoolAmountOut(pAo, Ti)) ```//uint tAi = tAiAfterFee / (1 - (1-weightTi) * swapFee) ;uint zar = bmul(bsub(BONE, normalizedWeight), swapFee);
tokenAmountIn = bdiv(tokenAmountInAfterFee, bsub(BONE, zar));
return tokenAmountIn;
}
/**********************************************************************************************
// calcSingleOutGivenPoolIn //
// tAo = tokenAmountOut / / \\ //
// bO = tokenBalanceOut / // pS - pAi \ / 1 \ \\ //
// pAi = poolAmountIn | bO - || ----------------------- | ^ | --------- | * b0 || //
// ps = poolSupply \ \\ pS / \(wO / tW)/ // //
// wI = tokenWeightIn tAo = \ \ // //
// tW = totalWeight / / wO \ \ //
// sF = swapFee * | 1 - | 1 - ---- | * sF | //
// eF = exitFee \ \ tW / / //
**********************************************************************************************/functioncalcSingleOutGivenPoolIn(uint tokenBalanceOut,
uint tokenWeightOut,
uint poolSupply,
uint totalWeight,
uint poolAmountIn,
uint swapFee
)
publicpurereturns (uint tokenAmountOut)
{
uint normalizedWeight = bdiv(tokenWeightOut, totalWeight);
uint newPoolSupply = bsub(poolSupply, poolAmountIn);
uint poolRatio = bdiv(newPoolSupply, poolSupply);
// newBalTo = poolRatio^(1/weightTo) * balTo;uint tokenOutRatio = bpow(poolRatio, bdiv(BONE, normalizedWeight));
uint newTokenBalanceOut = bmul(tokenOutRatio, tokenBalanceOut);
uint tokenAmountOutBeforeSwapFee = bsub(tokenBalanceOut, newTokenBalanceOut);
// charge swap fee on the output token side//uint tAo = tAoBeforeSwapFee * (1 - (1-weightTo) * swapFee)uint zaz = bmul(bsub(BONE, normalizedWeight), swapFee);
tokenAmountOut = bmul(tokenAmountOutBeforeSwapFee, bsub(BONE, zaz));
return tokenAmountOut;
}
/**********************************************************************************************
// calcPoolInGivenSingleOut //
// pAi = poolAmountIn // / tAo \\ / wO \ \ //
// bO = tokenBalanceOut // | bO - -------------------------- |\ | ---- | \ //
// tAo = tokenAmountOut pS - || \ 1 - ((1 - (tO / tW)) * sF)/ | ^ \ tW / * pS | //
// ps = poolSupply \\ -----------------------------------/ / //
// wO = tokenWeightOut pAi = \\ bO / / //
// tW = totalWeight //
// sF = swapFee //
**********************************************************************************************/functioncalcPoolInGivenSingleOut(uint tokenBalanceOut,
uint tokenWeightOut,
uint poolSupply,
uint totalWeight,
uint tokenAmountOut,
uint swapFee
)
publicpurereturns (uint poolAmountIn)
{
// charge swap fee on the output token sideuint normalizedWeight = bdiv(tokenWeightOut, totalWeight);
//uint tAoBeforeSwapFee = tAo / (1 - (1-weightTo) * swapFee) ;uint zoo = bsub(BONE, normalizedWeight);
uint zar = bmul(zoo, swapFee);
uint tokenAmountOutBeforeSwapFee = bdiv(tokenAmountOut, bsub(BONE, zar));
uint newTokenBalanceOut = bsub(tokenBalanceOut, tokenAmountOutBeforeSwapFee);
uint tokenOutRatio = bdiv(newTokenBalanceOut, tokenBalanceOut);
//uint newPoolSupply = (ratioTo ^ weightTo) * poolSupply;uint poolRatio = bpow(tokenOutRatio, normalizedWeight);
uint newPoolSupply = bmul(poolRatio, poolSupply);
uint poolAmountIn = bsub(poolSupply, newPoolSupply);
return poolAmountIn;
}
}
// SPDX-License-Identifier: GPL-3.0// This program is free software: you can redistribute it and/or modify// it under the terms of the GNU General Public License as published by// the Free Software Foundation, either version 3 of the License, or// (at your option) any later version.// This program is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the// GNU General Public License for more details.// You should have received a copy of the GNU General Public License// along with this program. If not, see <http://www.gnu.org/licenses/>.pragmasolidity 0.6.12;import"./BConst.sol";
contractBNumisBConst{
functionbtoi(uint a)
internalpurereturns (uint)
{
return a / BONE;
}
functionbfloor(uint a)
internalpurereturns (uint)
{
return btoi(a) * BONE;
}
functionbadd(uint a, uint b)
internalpurereturns (uint)
{
uint c = a + b;
require(c >= a, "ERR_ADD_OVERFLOW");
return c;
}
functionbsub(uint a, uint b)
internalpurereturns (uint)
{
(uint c, bool flag) = bsubSign(a, b);
require(!flag, "ERR_SUB_UNDERFLOW");
return c;
}
functionbsubSign(uint a, uint b)
internalpurereturns (uint, bool)
{
if (a >= b) {
return (a - b, false);
} else {
return (b - a, true);
}
}
functionbmul(uint a, uint b)
internalpurereturns (uint)
{
uint c0 = a * b;
require(a ==0|| c0 / a == b, "ERR_MUL_OVERFLOW");
uint c1 = c0 + (BONE /2);
require(c1 >= c0, "ERR_MUL_OVERFLOW");
uint c2 = c1 / BONE;
return c2;
}
functionbdiv(uint a, uint b)
internalpurereturns (uint)
{
require(b !=0, "ERR_DIV_ZERO");
uint c0 = a * BONE;
require(a ==0|| c0 / a == BONE, "ERR_DIV_INTERNAL"); // bmul overflowuint c1 = c0 + (b /2);
require(c1 >= c0, "ERR_DIV_INTERNAL"); // badd requireuint c2 = c1 / b;
return c2;
}
functiondiv(uint256 a, uint256 b) internalpurereturns (uint256) {
require(b >0, "ERR_DIV_ZERO");
return a / b;
}
// DSMath.wpowfunctionbpowi(uint a, uint n)
internalpurereturns (uint)
{
uint z = n %2!=0 ? a : BONE;
for (n /=2; n !=0; n /=2) {
a = bmul(a, a);
if (n %2!=0) {
z = bmul(z, a);
}
}
return z;
}
// Compute b^(e.w) by splitting it into (b^e)*(b^0.w).// Use `bpowi` for `b^e` and `bpowK` for k iterations// of approximation of b^0.wfunctionbpow(uint base, uint exp)
internalpurereturns (uint)
{
require(base >= MIN_BPOW_BASE, "ERR_BPOW_BASE_TOO_LOW");
require(base <= MAX_BPOW_BASE, "ERR_BPOW_BASE_TOO_HIGH");
uint whole = bfloor(exp);
uint remain = bsub(exp, whole);
uint wholePow = bpowi(base, btoi(whole));
if (remain ==0) {
return wholePow;
}
uint partialResult = bpowApprox(base, remain, BPOW_PRECISION);
return bmul(wholePow, partialResult);
}
functionbpowApprox(uint base, uint exp, uint precision)
internalpurereturns (uint)
{
// term 0:uint a = exp;
(uint x, bool xneg) = bsubSign(base, BONE);
uint term = BONE;
uint sum = term;
bool negative =false;
// term(k) = numer / denom// = (product(a - i - 1, i=1-->k) * x^k) / (k!)// each iteration, multiply previous term by (a-(k-1)) * x / k// continue until term is less than precisionfor (uint i =1; term >= precision; i++) {
uint bigK = i * BONE;
(uint c, bool cneg) = bsubSign(a, bsub(bigK, BONE));
term = bmul(term, bmul(c, x));
term = bdiv(term, bigK);
if (term ==0) break;
if (xneg) negative =!negative;
if (cneg) negative =!negative;
if (negative) {
sum = bsub(sum, term);
} else {
sum = badd(sum, term);
}
}
return sum;
}
}
// SPDX-License-Identifier: GPL-3.0// This program is free software: you can redistribute it and/or modify// it under the terms of the GNU General Public License as published by// the Free Software Foundation, either version 3 of the License, or// (at your option) any later version.// This program is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the// GNU General Public License for more details.// You should have received a copy of the GNU General Public License// along with this program. If not, see <http://www.gnu.org/licenses/>.pragmasolidity 0.6.12;import"@openzeppelin/contracts/token/ERC20/IERC20.sol";
import"./BNum.sol";
contractBTokenBaseisBNum{
mapping(address=>uint) internal _balance;
mapping(address=>mapping(address=>uint)) internal _allowance;
uintinternal _totalSupply;
eventApproval(addressindexed src, addressindexed dst, uint amt);
eventTransfer(addressindexed src, addressindexed dst, uint amt);
function_mint(uint amt) internal{
_balance[address(this)] = badd(_balance[address(this)], amt);
_totalSupply = badd(_totalSupply, amt);
emit Transfer(address(0), address(this), amt);
}
function_burn(uint amt) internal{
require(_balance[address(this)] >= amt, "ERR_INSUFFICIENT_BAL");
_balance[address(this)] = bsub(_balance[address(this)], amt);
_totalSupply = bsub(_totalSupply, amt);
emit Transfer(address(this), address(0), amt);
}
function_move(address src, address dst, uint amt) internal{
require(_balance[src] >= amt, "ERR_INSUFFICIENT_BAL");
_validateAddress(src);
_validateAddress(dst);
_balance[src] = bsub(_balance[src], amt);
_balance[dst] = badd(_balance[dst], amt);
emit Transfer(src, dst, amt);
}
function_push(address to, uint amt) internal{
_move(address(this), to, amt);
}
function_pull(addressfrom, uint amt) internal{
_move(from, address(this), amt);
}
function_validateAddress(address addr) internal{
require(addr !=address(0), "ERR_NULL_ADDRESS");
}
}
contractBTokenisBTokenBase, IERC20{
stringinternal _name;
stringinternal _symbol;
uint8private _decimals =18;
functionname() publicviewreturns (stringmemory) {
return _name;
}
functionsymbol() publicviewreturns (stringmemory) {
return _symbol;
}
functiondecimals() publicviewreturns(uint8) {
return _decimals;
}
functionallowance(address src, address dst) externaloverrideviewreturns (uint) {
return _allowance[src][dst];
}
functionbalanceOf(address whom) externaloverrideviewreturns (uint) {
return _balance[whom];
}
functiontotalSupply() publicoverrideviewreturns (uint) {
return _totalSupply;
}
functionapprove(address dst, uint amt) externaloverridereturns (bool) {
_validateAddress(dst);
_allowance[msg.sender][dst] = amt;
emit Approval(msg.sender, dst, amt);
returntrue;
}
functionincreaseApproval(address dst, uint amt) externalreturns (bool) {
_validateAddress(dst);
_allowance[msg.sender][dst] = badd(_allowance[msg.sender][dst], amt);
emit Approval(msg.sender, dst, _allowance[msg.sender][dst]);
returntrue;
}
functiondecreaseApproval(address dst, uint amt) externalreturns (bool) {
_validateAddress(dst);
uint oldValue = _allowance[msg.sender][dst];
if (amt > oldValue) {
_allowance[msg.sender][dst] =0;
} else {
_allowance[msg.sender][dst] = bsub(oldValue, amt);
}
emit Approval(msg.sender, dst, _allowance[msg.sender][dst]);
returntrue;
}
functiontransfer(address dst, uint amt) externaloverridereturns (bool) {
_move(msg.sender, dst, amt);
returntrue;
}
functiontransferFrom(address src, address dst, uint amt) externaloverridereturns (bool) {
require(msg.sender== src || amt <= _allowance[src][msg.sender], "ERR_BTOKEN_BAD_CALLER");
_move(src, dst, amt);
if (msg.sender!= src && _allowance[src][msg.sender] !=uint256(-1)) {
_allowance[src][msg.sender] = bsub(_allowance[src][msg.sender], amt);
emit Approval(src, msg.sender, _allowance[src][msg.sender]);
}
returntrue;
}
}
Código Fuente del Contrato
Archivo 8 de 11: IERC20.sol
// SPDX-License-Identifier: MITpragmasolidity ^0.6.0;/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/interfaceIERC20{
/**
* @dev Returns the amount of tokens in existence.
*/functiontotalSupply() externalviewreturns (uint256);
/**
* @dev Returns the amount of tokens owned by `account`.
*/functionbalanceOf(address account) externalviewreturns (uint256);
/**
* @dev Moves `amount` tokens from the caller's account to `recipient`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/functiontransfer(address recipient, uint256 amount) externalreturns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/functionallowance(address owner, address spender) externalviewreturns (uint256);
/**
* @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/functionapprove(address spender, uint256 amount) externalreturns (bool);
/**
* @dev Moves `amount` tokens from `sender` to `recipient` using the
* allowance mechanism. `amount` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/functiontransferFrom(address sender, address recipient, uint256 amount) externalreturns (bool);
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/eventTransfer(addressindexedfrom, addressindexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/eventApproval(addressindexed owner, addressindexed spender, uint256 value);
}