diff --git a/.eslintrc b/.eslintrc index 5e9d9c1..0574ca3 100644 --- a/.eslintrc +++ b/.eslintrc @@ -1,6 +1,6 @@ { "extends": [ - "airbnb" + "eslint:recommended" ], "rules": { "indent": ["error", 4], diff --git a/.solcover.js b/.solcover.js index 1a3090b..72796c4 100644 --- a/.solcover.js +++ b/.solcover.js @@ -1,9 +1,10 @@ module.exports = { port: 8555, skipFiles: [ - 'Migrations.sol', - 'DSProxyFactory.sol', - 'test' + 'test', + 'common', + 'v1', + 'v2', ], testrpcOptions: "-p 8555 -d" }; diff --git a/contracts/BActions.sol b/contracts/BActions.sol index 1ee7905..ccc8d05 100644 --- a/contracts/BActions.sol +++ b/contracts/BActions.sol @@ -34,6 +34,7 @@ abstract contract AbstractPool is ERC20, BalancerOwnable { function joinswapExternAmountIn( address tokenIn, uint tokenAmountIn, uint minPoolAmountOut ) external virtual returns (uint poolAmountOut); + function exitPool(uint poolAmountIn, uint[] calldata minAmountsOut) external virtual; } abstract contract BPool is AbstractPool { @@ -51,6 +52,29 @@ abstract contract BFactory { function newBPool() external virtual returns (BPool); } +abstract contract BalancerPool is ERC20 { + function getPoolId() external view virtual returns (bytes32); + + enum JoinKind { INIT, EXACT_TOKENS_IN_FOR_BPT_OUT } +} + +abstract contract Vault { + struct JoinPoolRequest { + address[] assets; + uint256[] maxAmountsIn; + bytes userData; + bool fromInternalBalance; + } + + function joinPool( + bytes32 poolId, + address sender, + address recipient, + JoinPoolRequest calldata request + ) external virtual; + function getPoolTokens(bytes32 poolId) external view virtual returns (address[] memory, uint[] memory, uint256); +} + abstract contract ConfigurableRightsPool is AbstractPool { struct PoolParams { string poolTokenSymbol; @@ -347,16 +371,125 @@ contract BActions { ) external { crp.removeWhitelistedLiquidityProvider(provider); } + + // --- Migration --- + + function migrateProportionally( + Vault vault, + BPool poolIn, + uint poolInAmount, + uint[] calldata tokenOutAmountsMin, + BalancerPool poolOut, + uint poolOutAmountMin + ) external { + address[] memory tokens = poolIn.getFinalTokens(); + (address[] memory outTokens, uint[] memory tokenInAmounts,) = + vault.getPoolTokens(poolOut.getPoolId()); + require(tokens.length == 2); + require(outTokens.length == 2); + require((tokens[0] == outTokens[0]) || (tokens[0] == outTokens[1])); + require((tokens[1] == outTokens[0]) || (tokens[1] == outTokens[1])); + // Transfer v1 BPTs to proxy + poolIn.transferFrom(msg.sender, address(this), poolInAmount); + // Exit v1 pool + poolIn.exitPool(poolInAmount, tokenOutAmountsMin); + // Approve each token to v2 vault + for (uint i = 0; i < tokens.length; i++) { + _safeApprove(ERC20(tokens[i]), address(vault), uint(-1)); + } + // Calculate amounts for even join + // 1) find the lowest UserBalance-to-PoolBalance ratio + // 2) multiply by this ratio to get in amounts + uint lowestRatio = uint(-1); + uint lowestRatioToken = 0; + for (uint i = 0; i < outTokens.length; ++i) { + uint ratio = 1 ether * ERC20(outTokens[i]).balanceOf(address(this)) / tokenInAmounts[i]; + if (ratio < lowestRatio) { + lowestRatio = ratio; + lowestRatioToken = i; + } + } + for (uint i = 0; i < outTokens.length; ++i) { + // Keep original amount for "bottleneck" token to avoid dust + if (lowestRatioToken == i) { + tokenInAmounts[i] = ERC20(outTokens[i]).balanceOf(address(this)); + } else { + tokenInAmounts[i] = tokenInAmounts[i] * lowestRatio / 1 ether; + } + } + // Join v2 pool and transfer v2 BPTs to user + bytes memory userData = abi.encode( + BalancerPool.JoinKind.EXACT_TOKENS_IN_FOR_BPT_OUT, + tokenInAmounts, + poolOutAmountMin + ); + Vault.JoinPoolRequest memory request = Vault.JoinPoolRequest(outTokens, tokenInAmounts, userData, false); + vault.joinPool( + poolOut.getPoolId(), + address(this), + msg.sender, + request + ); + // Send "change" back + for (uint i = 0; i < tokens.length; i++) { + ERC20 token = ERC20(tokens[i]); + if (token.balanceOf(address(this)) > 0) { + require(token.transfer(msg.sender, token.balanceOf(address(this))), "ERR_TRANSFER_FAILED"); + } + } + } + + function migrateAll( + Vault vault, + BPool poolIn, + uint poolInAmount, + uint[] calldata tokenOutAmountsMin, + BalancerPool poolOut, + uint poolOutAmountMin + ) external { + address[] memory tokens = poolIn.getFinalTokens(); + (address[] memory outTokens,,) = vault.getPoolTokens(poolOut.getPoolId()); + require(tokens.length == 2); + require(outTokens.length == 2); + require((tokens[0] == outTokens[0]) || (tokens[0] == outTokens[1])); + require((tokens[1] == outTokens[0]) || (tokens[1] == outTokens[1])); + // Transfer v1 BPTs to proxy + poolIn.transferFrom(msg.sender, address(this), poolInAmount); + // Exit v1 pool + poolIn.exitPool(poolInAmount, tokenOutAmountsMin); + // Approve each token to v2 vault + for (uint i = 0; i < tokens.length; i++) { + _safeApprove(ERC20(tokens[i]), address(vault), uint(-1)); + } + // Join v2 pool and transfer v2 BPTs to user + uint[] memory tokenInAmounts = new uint[](outTokens.length); + for (uint i = 0; i < outTokens.length; ++i) { + tokenInAmounts[i] = ERC20(outTokens[i]).balanceOf(address(this)); + } + + bytes memory userData = abi.encode( + BalancerPool.JoinKind.EXACT_TOKENS_IN_FOR_BPT_OUT, + tokenInAmounts, + poolOutAmountMin + ); + Vault.JoinPoolRequest memory request = Vault.JoinPoolRequest(outTokens, tokenInAmounts, userData, false); + vault.joinPool( + poolOut.getPoolId(), + address(this), + msg.sender, + request + ); + } // --- Internals --- - + function _safeApprove(ERC20 token, address spender, uint amount) internal { if (token.allowance(address(this), spender) > 0) { token.approve(spender, 0); } token.approve(spender, amount); } - + function _join( AbstractPool pool, address[] memory tokens, diff --git a/contracts/DSProxyFactory.sol b/contracts/common/DSProxyFactory.sol similarity index 100% rename from contracts/DSProxyFactory.sol rename to contracts/common/DSProxyFactory.sol diff --git a/contracts/test/IERC20.sol b/contracts/common/IERC20.sol similarity index 100% rename from contracts/test/IERC20.sol rename to contracts/common/IERC20.sol diff --git a/contracts/test/SafeApprove.sol b/contracts/common/SafeApprove.sol similarity index 100% rename from contracts/test/SafeApprove.sol rename to contracts/common/SafeApprove.sol diff --git a/contracts/test/TToken.sol b/contracts/common/TToken.sol similarity index 100% rename from contracts/test/TToken.sol rename to contracts/common/TToken.sol diff --git a/contracts/test/TTokenFactory.sol b/contracts/common/TTokenFactory.sol similarity index 100% rename from contracts/test/TTokenFactory.sol rename to contracts/common/TTokenFactory.sol diff --git a/contracts/test/BColor.sol b/contracts/v1/BColor.sol similarity index 100% rename from contracts/test/BColor.sol rename to contracts/v1/BColor.sol diff --git a/contracts/test/BConst.sol b/contracts/v1/BConst.sol similarity index 100% rename from contracts/test/BConst.sol rename to contracts/v1/BConst.sol diff --git a/contracts/test/BFactory.sol b/contracts/v1/BFactory.sol similarity index 100% rename from contracts/test/BFactory.sol rename to contracts/v1/BFactory.sol diff --git a/contracts/test/BMath.sol b/contracts/v1/BMath.sol similarity index 98% rename from contracts/test/BMath.sol rename to contracts/v1/BMath.sol index 060f809..a6019b2 100644 --- a/contracts/test/BMath.sol +++ b/contracts/v1/BMath.sol @@ -114,10 +114,6 @@ contract BMath is BBronze, BConst, BNum { public pure returns (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)); diff --git a/contracts/test/BNum.sol b/contracts/v1/BNum.sol similarity index 100% rename from contracts/test/BNum.sol rename to contracts/v1/BNum.sol diff --git a/contracts/test/BPool.sol b/contracts/v1/BPool.sol similarity index 100% rename from contracts/test/BPool.sol rename to contracts/v1/BPool.sol diff --git a/contracts/test/BToken.sol b/contracts/v1/BToken.sol similarity index 100% rename from contracts/test/BToken.sol rename to contracts/v1/BToken.sol diff --git a/contracts/test/BalancerConstants.sol b/contracts/v1/BalancerConstants.sol similarity index 100% rename from contracts/test/BalancerConstants.sol rename to contracts/v1/BalancerConstants.sol diff --git a/contracts/test/BalancerOwnable.sol b/contracts/v1/BalancerOwnable.sol similarity index 100% rename from contracts/test/BalancerOwnable.sol rename to contracts/v1/BalancerOwnable.sol diff --git a/contracts/test/BalancerReentrancyGuard.sol b/contracts/v1/BalancerReentrancyGuard.sol similarity index 100% rename from contracts/test/BalancerReentrancyGuard.sol rename to contracts/v1/BalancerReentrancyGuard.sol diff --git a/contracts/test/BalancerSafeMath.sol b/contracts/v1/BalancerSafeMath.sol similarity index 100% rename from contracts/test/BalancerSafeMath.sol rename to contracts/v1/BalancerSafeMath.sol diff --git a/contracts/test/CRPFactory.sol b/contracts/v1/CRPFactory.sol similarity index 100% rename from contracts/test/CRPFactory.sol rename to contracts/v1/CRPFactory.sol diff --git a/contracts/test/ConfigurableRightsPool.sol b/contracts/v1/ConfigurableRightsPool.sol similarity index 99% rename from contracts/test/ConfigurableRightsPool.sol rename to contracts/v1/ConfigurableRightsPool.sol index 72bb360..9b0333a 100644 --- a/contracts/test/ConfigurableRightsPool.sol +++ b/contracts/v1/ConfigurableRightsPool.sol @@ -14,9 +14,9 @@ import "./BalancerOwnable.sol"; // Interfaces // Libraries +import "../common/SafeApprove.sol"; import { RightsManager } from "./RightsManager.sol"; import "./SmartPoolManager.sol"; -import "./SafeApprove.sol"; // Contracts diff --git a/contracts/test/IBFactory.sol b/contracts/v1/IBFactory.sol similarity index 100% rename from contracts/test/IBFactory.sol rename to contracts/v1/IBFactory.sol diff --git a/contracts/test/PCToken.sol b/contracts/v1/PCToken.sol similarity index 99% rename from contracts/test/PCToken.sol rename to contracts/v1/PCToken.sol index a2c5b86..8fc081d 100644 --- a/contracts/test/PCToken.sol +++ b/contracts/v1/PCToken.sol @@ -3,9 +3,9 @@ pragma solidity 0.6.12; // Imports +import "../common/IERC20.sol"; import "./BalancerSafeMath.sol"; import "./BalancerConstants.sol"; -import "./IERC20.sol"; // Contracts diff --git a/contracts/test/RightsManager.sol b/contracts/v1/RightsManager.sol similarity index 100% rename from contracts/test/RightsManager.sol rename to contracts/v1/RightsManager.sol diff --git a/contracts/test/SmartPoolManager.sol b/contracts/v1/SmartPoolManager.sol similarity index 99% rename from contracts/test/SmartPoolManager.sol rename to contracts/v1/SmartPoolManager.sol index 30379c0..f092322 100644 --- a/contracts/test/SmartPoolManager.sol +++ b/contracts/v1/SmartPoolManager.sol @@ -6,12 +6,12 @@ pragma experimental ABIEncoderV2; // Imports -import "./IERC20.sol"; +import "../common/IERC20.sol"; +import "../common/SafeApprove.sol"; import "./ConfigurableRightsPool.sol"; import "./IBFactory.sol"; import "./BalancerConstants.sol"; import "./BalancerSafeMath.sol"; -import "./SafeApprove.sol"; /** diff --git a/contracts/v2/BalancerPool.sol b/contracts/v2/BalancerPool.sol new file mode 100644 index 0000000..46258d9 --- /dev/null +++ b/contracts/v2/BalancerPool.sol @@ -0,0 +1,227 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity 0.6.12; + +import './Vault.sol'; +import './LogExpMath.sol'; + +// BalancerPool mock; does not represent the actual BalancerPool design +contract BalancerPool { + Vault _vault; + string _name; + string _symbol; + bytes32 _poolId; + + uint256 _swapFee; + mapping(address => uint256) private _weight; + uint256 private _totalWeight; + + mapping(address => uint256) private _balance; + uint256 private _totalSupply; + + uint128 internal constant ONE = 10**18; + + function create( + Vault vault, + bytes32 poolId, + string memory name, + string memory symbol, + IERC20[] memory tokens, + uint256[] memory weights, + uint256 swapFee + ) external { + _vault = vault; + _poolId = poolId; + + _name = name; + _symbol = symbol; + _swapFee = swapFee; + + for (uint8 i = 0; i < weights.length; i++) { + _totalWeight = _totalWeight + weights[i]; + } + } + + enum JoinKind { INIT, EXACT_TOKENS_IN_FOR_BPT_OUT } + + function onJoinPool( + bytes32 poolId, + address, // sender - potential whitelisting + address recipient, + uint256[] memory currentBalances, + uint256[] memory maxAmountsIn, + uint256 protocolFeePercentage, + bytes memory userData + ) external returns (uint256[] memory, uint256[] memory) { + require(msg.sender == address(_vault), "ERR_CALLER_NOT_VAULT"); + require(poolId == _poolId, "INVALID_POOL_ID"); + + IERC20[] memory tokens = _vault.getPoolTokens(poolId); + uint256[] memory normalizedWeights = new uint256[](tokens.length); + for (uint8 i = 0; i < tokens.length; i++) { + normalizedWeights[i] = _weight[address(tokens[i])] / _totalWeight; + } + + // The Vault guarantees currentBalances and maxAmountsIn have the same length + + JoinKind kind = abi.decode(userData, (JoinKind)); + + if (kind == JoinKind.INIT) { + //Max amounts in are equal to amounts in. + return _joinInitial(normalizedWeights, recipient, maxAmountsIn); + } else { + // JoinKind.EXACT_TOKENS_IN_FOR_BPT_OUT + //Max amounts in are equal to exact amounts in. + (, uint256 minimumBPT) = abi.decode(userData, (JoinKind, uint256)); + return + _joinExactTokensInForBPTOut( + normalizedWeights, + currentBalances, + recipient, + maxAmountsIn, + minimumBPT, + protocolFeePercentage + ); + } + } + + function _joinInitial( + uint256[] memory normalizedWeights, + address recipient, + uint256[] memory amountsIn + ) private returns (uint256[] memory, uint256[] memory) { + require(totalSupply() == 0, "ERR_ALREADY_INITIALIZED"); + + // _lastInvariant should also be zero + uint256 invariantAfterJoin = _invariant(normalizedWeights, amountsIn); + + _mintPoolTokens(recipient, invariantAfterJoin); + + IERC20[] memory tokens = _vault.getPoolTokens(_poolId); + uint256[] memory dueProtocolFeeAmounts = new uint256[](tokens.length); // All zeroes + return (amountsIn, dueProtocolFeeAmounts); + } + + function _joinExactTokensInForBPTOut( + uint256[] memory normalizedWeights, + uint256[] memory currentBalances, + address recipient, + uint256[] memory amountsIn, + uint256 minimumBPT, + uint256 protocolFeePercentage + ) private returns (uint256[] memory, uint256[] memory) { + uint256 currentBPT = totalSupply(); + require(currentBPT > 0, "ERR_UNINITIALIZED"); + + uint256 bptAmountOut = _exactTokensInForBPTOut( + currentBalances, + normalizedWeights, + amountsIn, + currentBPT, + _swapFee + ); + + require(bptAmountOut >= minimumBPT, "ERR_BPT_OUT_MIN_AMOUNT"); + + _mintPoolTokens(recipient, bptAmountOut); + + IERC20[] memory tokens = _vault.getPoolTokens(_poolId); + for (uint8 i = 0; i < tokens.length; i++) { + currentBalances[i] = currentBalances[i] + amountsIn[i]; + } + + uint256[] memory dueProtocolFeeAmounts = new uint256[](tokens.length); // All zeroes + return (amountsIn, dueProtocolFeeAmounts); + } + + // Computes the invariant given the current balances and normalized weights. + function _invariant(uint256[] memory normalizedWeights, uint256[] memory balances) + internal + pure + returns (uint256 invariant) + { + /********************************************************************************************** + // invariant _____ // + // wi = weight index i | | wi // + // bi = balance index i | | bi ^ = i // + // i = invariant // + **********************************************************************************************/ + require(normalizedWeights.length == balances.length, "ERR_BALANCES_LENGTH"); + + invariant = ONE; + for (uint8 i = 0; i < normalizedWeights.length; i++) { + invariant = invariant * (LogExpMath.pow(balances[i], normalizedWeights[i])); + } + } + + function _exactTokensInForBPTOut( + uint256[] memory balances, + uint256[] memory normalizedWeights, + uint256[] memory amountsIn, + uint256 bptTotalSupply, + uint256 swapFee + ) internal pure returns (uint256) { + // First loop to calculate the weighted balance ratio + // The increment `amountIn` represents for each token, as a quotient of new and current balances, + // not accounting swap fees + uint256[] memory tokenBalanceRatiosWithoutFee = new uint256[](amountsIn.length); + // The weighted sum of token balance rations sans fee + uint256 weightedBalanceRatio = 0; + for (uint256 i = 0; i < balances.length; i++) { + tokenBalanceRatiosWithoutFee[i] = (balances[i] + amountsIn[i]) / balances[i]; + weightedBalanceRatio = weightedBalanceRatio + tokenBalanceRatiosWithoutFee[i] * normalizedWeights[i]; + } + + //Second loop to calculate new amounts in taking into account the fee on the % excess + // The growth of the invariant caused by the join, as a quotient of the new value and the current one + uint256 invariantRatio = ONE; + for (uint256 i = 0; i < balances.length; i++) { + // Percentage of the amount supplied that will be swapped for other tokens in the pool + uint256 tokenBalancePercentageExcess; + // Some tokens might have amounts supplied in excess of a 'balanced' join: these are identified if + // the token's balance ratio sans fee is larger than the weighted balance ratio, and swap fees charged + // on the amount to swap + if (weightedBalanceRatio >= tokenBalanceRatiosWithoutFee[i]) { + tokenBalancePercentageExcess = 0; + } else { + tokenBalancePercentageExcess = (tokenBalanceRatiosWithoutFee[i] - weightedBalanceRatio) / + tokenBalanceRatiosWithoutFee[i] - ONE; + } + + uint256 amountInAfterFee = amountsIn[i] * (ONE - swapFee * tokenBalancePercentageExcess); + + uint256 tokenBalanceRatio = ONE + amountInAfterFee / balances[i]; + + invariantRatio = invariantRatio * LogExpMath.pow(tokenBalanceRatio, normalizedWeights[i]); + } + + return bptTotalSupply * (invariantRatio - ONE); + } + + function totalSupply() public view returns (uint256) { + return _totalSupply; + } + + function balanceOf(address owner) public view returns (uint256){ + return _balance[owner]; + } + + function getPoolId() external view returns (bytes32) { + return _poolId; + } + + function _mintPoolTokens(address recipient, uint256 amount) internal { + _balance[address(this)] = _balance[address(this)] + amount; + _totalSupply = _totalSupply + amount; + + _move(address(this), recipient, amount); + } + + function _move( + address sender, + address recipient, + uint256 amount + ) internal { + _balance[sender] = _balance[sender] - amount; + _balance[recipient] = _balance[recipient] + amount; + } +} diff --git a/contracts/v2/LogExpMath.sol b/contracts/v2/LogExpMath.sol new file mode 100644 index 0000000..cf060d5 --- /dev/null +++ b/contracts/v2/LogExpMath.sol @@ -0,0 +1,293 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity 0.6.12; + +// There's plenty of linter errors caused by this file, we'll eventually +// revisit it to make it more readable, verfiable and testable. +/* solhint-disable */ + +/** + * @title Ethereum library for logarithm and exponential functions with 18 decimal precision. + * @author Fernando Martinelli - @fernandomartinelli + * @author Sergio Yuhjtman - @sergioyuhjtman + * @author Daniel Fernandez - @dmf7z + */ +library LogExpMath { + int256 constant DECIMALS = 10**18; + int256 constant DOUBLE_DECIMALS = DECIMALS * DECIMALS; + int256 constant PRECISION = 10**20; + int256 constant DOUBLE_PRECISION = PRECISION * PRECISION; + int256 constant PRECISION_LOG_UNDER_BOUND = DECIMALS - 10**17; + int256 constant PRECISION_LOG_UPPER_BOUND = DECIMALS + 10**17; + int256 constant EXPONENT_LB = -41446531673892822312; + int256 constant EXPONENT_UB = 130700829182905140221; + uint256 constant MILD_EXPONENT_BOUND = 2**254 / uint256(PRECISION); + + int256 constant x0 = 128000000000000000000; //2ˆ7 + int256 constant a0 = 38877084059945950922200000000000000000000000000000000000; //eˆ(x0) + int256 constant x1 = 64000000000000000000; //2ˆ6 + int256 constant a1 = 6235149080811616882910000000; //eˆ(x1) + int256 constant x2 = 3200000000000000000000; //2ˆ5 + int256 constant a2 = 7896296018268069516100000000000000; //eˆ(x2) + int256 constant x3 = 1600000000000000000000; //2ˆ4 + int256 constant a3 = 888611052050787263676000000; //eˆ(x3) + int256 constant x4 = 800000000000000000000; //2ˆ3 + int256 constant a4 = 298095798704172827474000; //eˆ(x4) + int256 constant x5 = 400000000000000000000; //2ˆ2 + int256 constant a5 = 5459815003314423907810; //eˆ(x5) + int256 constant x6 = 200000000000000000000; //2ˆ1 + int256 constant a6 = 738905609893065022723; //eˆ(x6) + int256 constant x7 = 100000000000000000000; //2ˆ0 + int256 constant a7 = 271828182845904523536; //eˆ(x7) + int256 constant x8 = 50000000000000000000; //2ˆ-1 + int256 constant a8 = 164872127070012814685; //eˆ(x8) + int256 constant x9 = 25000000000000000000; //2ˆ-2 + int256 constant a9 = 128402541668774148407; //eˆ(x9) + int256 constant x10 = 12500000000000000000; //2ˆ-3 + int256 constant a10 = 113314845306682631683; //eˆ(x10) + int256 constant x11 = 6250000000000000000; //2ˆ-4 + int256 constant a11 = 106449445891785942956; //eˆ(x11) + + /** + * Calculate the natural exponentiation of a number with 18 decimals precision. + * @param x Exponent with 18 decimal places. + * @notice Max x is log((2^255 - 1) / 10^20) = 130.700829182905140221 + * @notice Min x log(0.000000000000000001) = -41.446531673892822312 + * @return eˆx + */ + function n_exp(int256 x) internal pure returns (int256) { + require( + x >= EXPONENT_LB && x <= EXPONENT_UB, + "Natural exp argument must be between -41.446531673892822312 and 130.700829182905140221" + ); + if (x < 0) return (DOUBLE_DECIMALS / n_exp(-x)); + int256 ans = PRECISION; + int256 last = 1; + if (x >= x0) { + last = a0; + x -= x0; + } + if (x >= x1) { + last *= a1; + x -= x1; + } + x *= 100; + if (x >= x2) { + ans = (ans * a2) / PRECISION; + x -= x2; + } + if (x >= x3) { + ans = (ans * a3) / PRECISION; + x -= x3; + } + if (x >= x4) { + ans = (ans * a4) / PRECISION; + x -= x4; + } + if (x >= x5) { + ans = (ans * a5) / PRECISION; + x -= x5; + } + if (x >= x6) { + ans = (ans * a6) / PRECISION; + x -= x6; + } + if (x >= x7) { + ans = (ans * a7) / PRECISION; + x -= x7; + } + if (x >= x8) { + ans = (ans * a8) / PRECISION; + x -= x8; + } + if (x >= x9) { + ans = (ans * a9) / PRECISION; + x -= x9; + } + int256 s = PRECISION; + int256 t = x; + s += t; + t = ((t * x) / 2) / PRECISION; + s += t; + t = ((t * x) / 3) / PRECISION; + s += t; + t = ((t * x) / 4) / PRECISION; + s += t; + t = ((t * x) / 5) / PRECISION; + s += t; + t = ((t * x) / 6) / PRECISION; + s += t; + t = ((t * x) / 7) / PRECISION; + s += t; + t = ((t * x) / 8) / PRECISION; + s += t; + t = ((t * x) / 9) / PRECISION; + s += t; + t = ((t * x) / 10) / PRECISION; + s += t; + t = ((t * x) / 11) / PRECISION; + s += t; + t = ((t * x) / 12) / PRECISION; + s += t; + return (((ans * s) / PRECISION) * last) / 100; + } + + /** + * Calculate the natural logarithm of a number with 18 decimals precision. + * @param a Positive number with 18 decimal places. + * @return ln(x) + */ + function n_log(int256 a) internal pure returns (int256) { + require(a > 0, "Natural log argument must be positive"); + if (a < DECIMALS) return (-n_log(DOUBLE_DECIMALS / a)); + int256 ans = 0; + if (a >= a0 * DECIMALS) { + ans += x0; + a /= a0; + } + if (a >= a1 * DECIMALS) { + ans += x1; + a /= a1; + } + a *= 100; + ans *= 100; + if (a >= a2) { + ans += x2; + a = (a * PRECISION) / a2; + } + if (a >= a3) { + ans += x3; + a = (a * PRECISION) / a3; + } + if (a >= a4) { + ans += x4; + a = (a * PRECISION) / a4; + } + if (a >= a5) { + ans += x5; + a = (a * PRECISION) / a5; + } + if (a >= a6) { + ans += x6; + a = (a * PRECISION) / a6; + } + if (a >= a7) { + ans += x7; + a = (a * PRECISION) / a7; + } + if (a >= a8) { + ans += x8; + a = (a * PRECISION) / a8; + } + if (a >= a9) { + ans += x9; + a = (a * PRECISION) / a9; + } + if (a >= a10) { + ans += x10; + a = (a * PRECISION) / a10; + } + if (a >= a11) { + ans += x11; + a = (a * PRECISION) / a11; + } + int256 z = (PRECISION * (a - PRECISION)) / (a + PRECISION); + int256 s = z; + int256 z_squared = (z * z) / PRECISION; + int256 t = (z * z_squared) / PRECISION; + s += t / 3; + t = (t * z_squared) / PRECISION; + s += t / 5; + t = (t * z_squared) / PRECISION; + s += t / 7; + t = (t * z_squared) / PRECISION; + s += t / 9; + t = (t * z_squared) / PRECISION; + s += t / 11; + return (ans + 2 * s) / 100; + } + + /** + * Computes x to the power of y for numbers with 18 decimals precision. + * @param x Base with 18 decimal places. + * @param y Exponent with 18 decimal places. + * @notice Must fulfil: -41.446531673892822312 < (log(x) * y) < 130.700829182905140221 + * @return xˆy + */ + function pow(uint256 x, uint256 y) internal pure returns (uint256) { + if (y == 0) { + return uint256(DECIMALS); + } + + if (x == 0) { + return 0; + } + + require(x < 2**255, "x must be less than 2**255"); // uint256 can be casted to a positive int256 + require(y < MILD_EXPONENT_BOUND, "input y has to be less than 2**254 / 10**20"); + int256 x_int256 = int256(x); + int256 y_int256 = int256(y); + int256 logx_times_y; + if (PRECISION_LOG_UNDER_BOUND < x_int256 && x_int256 < PRECISION_LOG_UPPER_BOUND) { + int256 logbase = n_log_36(x_int256); + logx_times_y = ((logbase / DECIMALS) * y_int256 + ((logbase % DECIMALS) * y_int256) / DECIMALS); + } else { + logx_times_y = n_log(x_int256) * y_int256; + } + require( + EXPONENT_LB * DECIMALS <= logx_times_y && logx_times_y <= EXPONENT_UB * DECIMALS, + "log(x) times y must be between -41.446531673892822312 and 130.700829182905140221" + ); + logx_times_y /= DECIMALS; + return uint256(n_exp(logx_times_y)); + } + + /** + * Computes log of a number in base of another number, both numbers with 18 decimals precision. + * @param arg Argument with 18 decimal places. + * @param base Base with 18 decimal places. + * @notice Must fulfil: -41.446531673892822312 < (log(x) * y) < 130.700829182905140221 + * @return log[base](arg) + */ + function log(int256 arg, int256 base) internal pure returns (int256) { + int256 logbase; + if (PRECISION_LOG_UNDER_BOUND < base && base < PRECISION_LOG_UPPER_BOUND) { + logbase = n_log_36(base); + } else { + logbase = n_log(base) * DECIMALS; + } + int256 logarg; + if (PRECISION_LOG_UNDER_BOUND < arg && arg < PRECISION_LOG_UPPER_BOUND) { + logarg = n_log_36(arg); + } else { + logarg = n_log(arg) * DECIMALS; + } + return (logarg * DECIMALS) / logbase; + } + + /** + * Private function to calculate the natural logarithm of a number with 36 decimals precision. + * @param a Positive number with 18 decimal places. + * @return ln(x) + */ + function n_log_36(int256 a) private pure returns (int256) { + a *= DECIMALS; + int256 z = (DOUBLE_DECIMALS * (a - DOUBLE_DECIMALS)) / (a + DOUBLE_DECIMALS); + int256 s = z; + int256 z_squared = (z * z) / DOUBLE_DECIMALS; + int256 t = (z * z_squared) / DOUBLE_DECIMALS; + s += t / 3; + t = (t * z_squared) / DOUBLE_DECIMALS; + s += t / 5; + t = (t * z_squared) / DOUBLE_DECIMALS; + s += t / 7; + t = (t * z_squared) / DOUBLE_DECIMALS; + s += t / 9; + t = (t * z_squared) / DOUBLE_DECIMALS; + s += t / 11; + t = (t * z_squared) / DOUBLE_DECIMALS; + s += t / 13; + t = (t * z_squared) / DOUBLE_DECIMALS; + s += t / 15; + return 2 * s; + } +} diff --git a/contracts/v2/Vault.sol b/contracts/v2/Vault.sol new file mode 100644 index 0000000..094b575 --- /dev/null +++ b/contracts/v2/Vault.sol @@ -0,0 +1,98 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity 0.6.12; + +pragma experimental ABIEncoderV2; + +import '../common/IERC20.sol'; +import './BalancerPool.sol'; + +// Vault mock; does not represent the actual Vault design +contract Vault { + struct JoinPoolRequest { + IERC20[] assets; + uint256[] maxAmountsIn; + bytes userData; + bool fromInternalBalance; + } + + uint256 _poolCount; + mapping(bytes32 => address) internal _poolAddresses; + mapping(bytes32 => IERC20[]) internal _poolTokens; + mapping(bytes32 => mapping(IERC20 => uint256)) internal _poolTokenBalance; + + function newPool(IERC20[] memory tokens, address poolAddress) external returns (bytes32) { + bytes32 poolId = bytes32(_poolCount); + _poolTokens[poolId] = tokens; + _poolAddresses[poolId] = poolAddress; + _poolCount = _poolCount + 1; + return poolId; + } + + function getPoolTokens(bytes32 poolId) external returns (IERC20[] memory) { + return _poolTokens[poolId]; + } + + function getPoolTokenBalances(bytes32 poolId, IERC20[] memory tokens) + public + view + returns (uint256[] memory) + { + uint256[] memory balances = new uint256[](tokens.length); + for (uint256 i = 0; i < tokens.length; ++i) { + balances[i] = _poolTokenBalance[poolId][tokens[i]]; + } + + return balances; + } + + function joinPool( + bytes32 poolId, + address sender, + address recipient, + JoinPoolRequest memory request + ) external { + require(request.assets.length == request.maxAmountsIn.length, "ERR_TOKENS_AMOUNTS_LENGTH_MISMATCH"); + + uint256[] memory currentBalances = getPoolTokenBalances(poolId, request.assets); + + address pool = _poolAddresses[poolId]; + (uint256[] memory amountsIn,) = BalancerPool(pool).onJoinPool( + poolId, + sender, + recipient, + currentBalances, + request.maxAmountsIn, + 0, + request.userData + ); + + for (uint256 i = 0; i < request.assets.length; ++i) { + if (amountsIn[i] > 0) { + _increasePoolCash(poolId, request.assets[i], amountsIn[i]); + } + } + } + + function _pullTokens( + IERC20 token, + address from, + uint256 amount + ) internal returns (uint256) { + if (amount == 0) { + return 0; + } + uint256 currentBalance = token.balanceOf(address(this)); + token.transferFrom(from, address(this), amount); + uint256 newBalance = token.balanceOf(address(this)); + return newBalance - currentBalance; + } + + function _increasePoolCash( + bytes32 poolId, + IERC20 token, + uint256 amount + ) internal { + uint256 currentBalance = _poolTokenBalance[poolId][token]; + _poolTokenBalance[poolId][token] = currentBalance + amount; + } +} diff --git a/migrations/2_deploy_proxy.js b/migrations/2_deploy_proxy.js index e57e5f3..dd4c1af 100644 --- a/migrations/2_deploy_proxy.js +++ b/migrations/2_deploy_proxy.js @@ -4,8 +4,10 @@ const CRPFactory = artifacts.require('CRPFactory'); const BalancerSafeMath = artifacts.require('BalancerSafeMath'); const BActions = artifacts.require('BActions'); const BFactory = artifacts.require('BFactory'); +const BalancerPool = artifacts.require('BalancerPool'); +const Vault = artifacts.require('Vault'); -module.exports = async function(deployer, network, accounts) { +module.exports = async function(deployer, network) { if (network == 'development' || network == 'soliditycoverage') { await deployer.deploy(RightsManager); await deployer.deploy(SmartPoolManager); @@ -15,9 +17,11 @@ module.exports = async function(deployer, network, accounts) { await deployer.link(BalancerSafeMath, CRPFactory); await deployer.link(RightsManager, CRPFactory); await deployer.link(SmartPoolManager, CRPFactory); - await deployer.deploy(CRPFactory); + await deployer.deploy(Vault); + await deployer.deploy(BalancerPool); + await deployer.deploy(BActions, BFactory.address); } else if (network == 'kovan-fork' || network == 'kovan') { deployer.deploy(BActions, '0x8f7F78080219d4066A8036ccD30D588B416a40DB'); diff --git a/migrations/3_test_factories.js b/migrations/3_test_factories.js index 3115af6..b0ab32d 100644 --- a/migrations/3_test_factories.js +++ b/migrations/3_test_factories.js @@ -1,7 +1,7 @@ const TTokenFactory = artifacts.require("TTokenFactory"); const DSProxyFactory = artifacts.require("DSProxyFactory"); -module.exports = async function(deployer, network, accounts) { +module.exports = async function(deployer, network) { if (network == 'development' || network == 'soliditycoverage') { deployer.deploy(TTokenFactory); deployer.deploy(DSProxyFactory); diff --git a/package.json b/package.json index 9930af0..4f503fa 100644 --- a/package.json +++ b/package.json @@ -24,10 +24,6 @@ "chai": "^4.2.0", "coveralls": "^3.0.8", "eslint": "^6.7.1", - "eslint-config-airbnb": "^18.0.1", - "eslint-plugin-import": "^2.18.2", - "eslint-plugin-jsx-a11y": "^6.2.3", - "eslint-plugin-react": "^7.17.0", "ganache-core": "^2.6.1", "mocha": "^6.2.0", "solhint": "^3.2.0", @@ -39,7 +35,7 @@ }, "dependencies": { "decimal.js": "^10.2.0", - "ganache-cli": "^6.7.0", + "ganache-cli": "^6.12.1", "global": "^4.4.0" } } diff --git a/test/migration.js b/test/migration.js new file mode 100644 index 0000000..fcc158e --- /dev/null +++ b/test/migration.js @@ -0,0 +1,216 @@ +const truffleAssert = require('truffle-assertions'); + +const TToken = artifacts.require('TToken'); +const TTokenFactory = artifacts.require('TTokenFactory'); +const BFactory = artifacts.require('BFactory'); +const BActions = artifacts.require('BActions'); +const DSProxyFactory = artifacts.require('DSProxyFactory'); +const DSProxy = artifacts.require('DSProxy'); +const BPool = artifacts.require('BPool'); +const Vault = artifacts.require('Vault'); +const BalancerPool = artifacts.require('BalancerPool'); + +contract('BActions', async (accounts) => { + const admin = accounts[0]; + const user1 = accounts[1]; + const { toHex, toWei, fromWei } = web3.utils; + + const MAX = web3.utils.toTwosComplement(-1); + + describe('Liquidity migration', () => { + let factory; + let FACTORY; + let proxyFactory; + let bactions; + let BACTIONS; + let tokens; + let USER_PROXY; + let userProxy; + let POOL_V1; + let VAULT; + let POOL_V2; + let dai; let mkr; let zrx; let weth; + let DAI; let MKR; let ZRX; let WETH; + + before(async () => { + proxyFactory = await DSProxyFactory.deployed(); + + bactions = await BActions.deployed(); + BACTIONS = bactions.address; + + await mintTokens(); + await setupProxy(); + await createV1Pool(); + await setupV2(); + }); + + async function mintTokens() { + tokens = await TTokenFactory.deployed(); + factory = await BFactory.deployed(); + FACTORY = factory.address; + + await tokens.build(toHex('DAI'), toHex('DAI'), 18); + await tokens.build(toHex('MKR'), toHex('MKR'), 18); + await tokens.build(toHex('ZRX'), toHex('ZRX'), 18); + await tokens.build(toHex('WETH'), toHex('WETH'), 18); + + DAI = await tokens.get.call(toHex('DAI')); + MKR = await tokens.get.call(toHex('MKR')); + ZRX = await tokens.get.call(toHex('ZRX')); + WETH = await tokens.get.call(toHex('WETH')); + + dai = await TToken.at(DAI); + mkr = await TToken.at(MKR); + zrx = await TToken.at(ZRX); + weth = await TToken.at(WETH); + + await dai.mint(admin, toWei('10000')); + await mkr.mint(admin, toWei('20')); + await zrx.mint(admin, toWei('100')); + await weth.mint(admin, toWei('40')); + + await dai.mint(user1, toWei('10000')); + await mkr.mint(user1, toWei('20')); + } + + async function setupProxy() { + USER_PROXY = await proxyFactory.build.call(); + await proxyFactory.build(); + userProxy = await DSProxy.at(USER_PROXY); + + await dai.approve(USER_PROXY, MAX); + await mkr.approve(USER_PROXY, MAX); + await zrx.approve(USER_PROXY, MAX); + await weth.approve(USER_PROXY, MAX); + } + + async function createV1Pool() { + const createTokens = [DAI, MKR, WETH]; + const createBalances = [toWei('400'), toWei('1'), toWei('2')]; + const createWeights = [toWei('5'), toWei('5'), toWei('5')]; + const swapFee = toWei('0.03'); + const finalize = true; + + const createInterface = BActions.abi.find((iface) => iface.name === 'create'); + + const params = [ + FACTORY, + createTokens, + createBalances, + createWeights, + swapFee, + finalize, + ]; + + const functionCall = web3.eth.abi.encodeFunctionCall(createInterface, params); + + const poolAddress = await userProxy.methods['execute(address,bytes)'].call( + BACTIONS, functionCall, + ); + POOL_V1 = `0x${poolAddress.slice(-40)}`; + + await userProxy.methods['execute(address,bytes)'](BACTIONS, functionCall); + } + + async function setupV2() { + const balancerPool = await BalancerPool.deployed(); + POOL_V2 = balancerPool.address; + + const vault = await Vault.deployed(); + VAULT = vault.address; + + await dai.approve(VAULT, MAX); + await mkr.approve(VAULT, MAX); + await zrx.approve(VAULT, MAX); + await weth.approve(VAULT, MAX); + + const id = '0x0'; + const name = 'Balancer Pool'; + const symbol = 'BPT'; + const tokens = [DAI, MKR, WETH]; + const balances = [toWei('200'), toWei('0.5'), toWei('1')]; + const weights = [toWei('5'), toWei('5'), toWei('5')]; + const swapFee = toWei('0.03'); + const initJoinData = '0x0000000000000000000000000000000000000000000000000000000000000000'; + vault.newPool(tokens, POOL_V2); + balancerPool.create(VAULT, id, name, symbol, tokens, weights, swapFee); + vault.joinPool(id, admin, tokens, balances, false, initJoinData); + } + + it('Proportional migration', async () => { + // Approve v1 BPT to proxy + const bpt = await BPool.at(POOL_V1); + await bpt.approve(USER_PROXY, MAX); + + const params = [ + VAULT, + POOL_V1, + toWei('10'), + [0, 0, 0], + POOL_V2, + 0, + ]; + + const startV1Balance = await bpt.balanceOf(admin); // should go 100 -> 0 + // const v2Pool = await BalancerPool.at(POOL_V2); + // const startV2Balance = await v2Pool.balanceOf(admin); // should go 100 -> 300 + + const functionSig = web3.eth.abi.encodeFunctionSignature( + 'migrateProportionally(address,address,uint256,uint256[],address,uint256)', + ); + const functionData = web3.eth.abi.encodeParameters( + ['address', 'address', 'uint256', 'uint256[]', 'address', 'uint256'], + params, + ); + + const argumentData = functionData.substring(2); + const inputData = `${functionSig}${argumentData}`; + + await userProxy.methods['execute(address,bytes)'](BACTIONS, inputData); + + const endV1Balance = await bpt.balanceOf(admin); + // const endV2Balance = await v2Pool.balanceOf(admin); + + assert.equal(fromWei(startV1Balance.sub(endV1Balance)), '10'); + // assert.equal(fromWei(endV2Balance.sub(startV2Balance)), '200'); + }); + + it('Full migration', async () => { + // Approve v1 BPT to proxy + const bpt = await BPool.at(POOL_V1); + await bpt.approve(USER_PROXY, MAX); + + const params = [ + VAULT, + POOL_V1, + toWei('10'), + [0, 0, 0], + POOL_V2, + 0, + ]; + + const startV1Balance = await bpt.balanceOf(admin); // should go 100 -> 0 + // const v2Pool = await BalancerPool.at(POOL_V2); + // const startV2Balance = await v2Pool.balanceOf(admin); // should go 100 -> 300 + + const functionSig = web3.eth.abi.encodeFunctionSignature( + 'migrateAll(address,address,uint256,uint256[],address,uint256)', + ); + const functionData = web3.eth.abi.encodeParameters( + ['address', 'address', 'uint256', 'uint256[]', 'address', 'uint256'], + params, + ); + + const argumentData = functionData.substring(2); + const inputData = `${functionSig}${argumentData}`; + + await userProxy.methods['execute(address,bytes)'](BACTIONS, inputData); + + const endV1Balance = await bpt.balanceOf(admin); + // const endV2Balance = await v2Pool.balanceOf(admin); + + assert.equal(fromWei(startV1Balance.sub(endV1Balance)), '10'); + // assert.equal(fromWei(endV2Balance.sub(startV2Balance)), '200'); + }); + }); +}); diff --git a/yarn.lock b/yarn.lock index 5d12ae7..d3c65cd 100644 --- a/yarn.lock +++ b/yarn.lock @@ -18,21 +18,6 @@ esutils "^2.0.2" js-tokens "^4.0.0" -"@babel/runtime-corejs3@^7.7.4": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/runtime-corejs3/-/runtime-corejs3-7.8.3.tgz#a2445836d0699e5ba77eea2c790ad9ea51e2cd27" - integrity sha512-lrIU4aVbmlM/wQPzhEvzvNJskKyYptuXb0fGC0lTQTupTOYtR2Vqbu6/jf8vTr4M8Wt1nIzxVrSvPI5qESa/xA== - dependencies: - core-js-pure "^3.0.0" - regenerator-runtime "^0.13.2" - -"@babel/runtime@^7.4.5", "@babel/runtime@^7.7.4": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.8.3.tgz#0811944f73a6c926bb2ad35e918dcc1bfab279f1" - integrity sha512-fVHx1rzEmwB130VTkLnxR+HmxcTjGzH12LYQcFFoBwakMd3aOMD4OsRN7tGG/UOYE2ektgFrS8uACAoRk1CY0w== - dependencies: - regenerator-runtime "^0.13.2" - "@nodelib/fs.scandir@2.1.3": version "2.1.3" resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz#3a582bdb53804c6ba6d146579c46e52130cf4a3b" @@ -137,6 +122,20 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-12.12.25.tgz#792c0afb798f1dd681dce9c4b4c431f7245a0a42" integrity sha512-nf1LMGZvgFX186geVZR1xMZKKblJiRfiASTHw85zED2kI1yDKHDwTKMdkaCbTlXoRKlGKaDfYywt+V0As30q3w== +"@types/pbkdf2@^3.0.0": + version "3.1.0" + resolved "https://registry.yarnpkg.com/@types/pbkdf2/-/pbkdf2-3.1.0.tgz#039a0e9b67da0cdc4ee5dab865caa6b267bb66b1" + integrity sha512-Cf63Rv7jCQ0LaL8tNXmEyqTHuIJxRdlS5vMh1mj5voN4+QFhVZnlZruezqpWYDiJ8UTzhP0VmeLXCmBk66YrMQ== + dependencies: + "@types/node" "*" + +"@types/secp256k1@^4.0.1": + version "4.0.1" + resolved "https://registry.yarnpkg.com/@types/secp256k1/-/secp256k1-4.0.1.tgz#fb3aa61a1848ad97d7425ff9dcba784549fca5a4" + integrity sha512-+ZjSA8ELlOp8SlKi0YLB2tz9d5iPNEmOBd+8Rz21wTMdaXQIa9b6TEnD6l5qKOCypE7FSyPyck12qZJxSDNoog== + dependencies: + "@types/node" "*" + "@web3-js/scrypt-shim@^0.1.0": version "0.1.0" resolved "https://registry.yarnpkg.com/@web3-js/scrypt-shim/-/scrypt-shim-0.1.0.tgz#0bf7529ab6788311d3e07586f7d89107c3bea2cc" @@ -372,14 +371,6 @@ argparse@^1.0.7: dependencies: sprintf-js "~1.0.2" -aria-query@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-3.0.0.tgz#65b3fcc1ca1155a8c9ae64d6eee297f15d5133cc" - integrity sha1-ZbP8wcoRVajJrmTW7uKX8V1RM8w= - dependencies: - ast-types-flow "0.0.7" - commander "^2.11.0" - arr-diff@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" @@ -419,7 +410,7 @@ array-flatten@1.1.1: resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" integrity sha1-ml9pkFGx5wczKPKgCJaLZOopVdI= -array-includes@^3.0.3, array-includes@^3.1.1: +array-includes@^3.0.3: version "3.1.1" resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.1.tgz#cdd67e6852bdf9c1215460786732255ed2459348" integrity sha512-c2VXaCHl7zPsvpkFsw4nxvFie4fh1ur9bpcgsVkIjqn0H/Xwdg+7fv3n2r/isyS8EBj5b06M9kHyZuIr4El6WQ== @@ -467,14 +458,6 @@ array-unique@^0.3.2: resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg= -array.prototype.flat@^1.2.1: - version "1.2.3" - resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.2.3.tgz#0de82b426b0318dbfdb940089e38b043d37f6c7b" - integrity sha512-gBlRZV0VSmfPIeWfuuy56XZMvbVfbEUnOXUvt3F/eUUUSyzlgLxhEX4YAEpxNAogRGehPSnfXyPtYyKAhkzQhQ== - dependencies: - define-properties "^1.1.3" - es-abstract "^1.17.0-next.1" - asn1.js@^4.0.0: version "4.10.1" resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-4.10.1.tgz#b9c2bf5805f1e64aadeed6df3a2bfafb5a73f5a0" @@ -511,11 +494,6 @@ ast-parents@0.0.1: resolved "https://registry.yarnpkg.com/ast-parents/-/ast-parents-0.0.1.tgz#508fd0f05d0c48775d9eccda2e174423261e8dd3" integrity sha1-UI/Q8F0MSHddnszaLhdEIyYejdM= -ast-types-flow@0.0.7, ast-types-flow@^0.0.7: - version "0.0.7" - resolved "https://registry.yarnpkg.com/ast-types-flow/-/ast-types-flow-0.0.7.tgz#f70b735c6bca1a5c9c22d982c3e39e7feba3bdad" - integrity sha1-9wtzXGvKGlycItmCw+Oef+ujva0= - astral-regex@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9" @@ -594,14 +572,6 @@ aws4@^1.8.0: resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.9.1.tgz#7e33d8f7d449b3f673cd72deb9abdc552dbe528e" integrity sha512-wMHVg2EOHaMRxbzgFJ9gtjOOCrI80OHLG14rxi28XwOW8ux6IiEbRCGGGqCtdAIg4FQCbW20k9RsT4y3gJlFug== -axobject-query@^2.0.2: - version "2.1.1" - resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-2.1.1.tgz#2a3b1271ec722d48a4cd4b3fcc20c853326a49a7" - integrity sha512-lF98xa/yvy6j3fBHAgQXIYl+J4eZadOSqsPojemUqClzNbBV38wWGpUbQbVEyf4eUF5yF7eHmGgGA2JiHyjeqw== - dependencies: - "@babel/runtime" "^7.7.4" - "@babel/runtime-corejs3" "^7.7.4" - babel-code-frame@^6.26.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b" @@ -1223,6 +1193,11 @@ bl@^1.0.0: readable-stream "^2.3.5" safe-buffer "^5.1.1" +blakejs@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/blakejs/-/blakejs-1.1.0.tgz#69df92ef953aa88ca51a32df6ab1c54a155fc7a5" + integrity sha1-ad+S75U6qIylGjLfarHFShVfx6U= + bluebird@^3.5.0: version "3.7.2" resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" @@ -1295,7 +1270,7 @@ browser-stdout@1.3.1: resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== -browserify-aes@^1.0.0, browserify-aes@^1.0.4, browserify-aes@^1.0.6: +browserify-aes@^1.0.0, browserify-aes@^1.0.4, browserify-aes@^1.0.6, browserify-aes@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48" integrity sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA== @@ -1758,11 +1733,6 @@ commander@2.18.0: resolved "https://registry.yarnpkg.com/commander/-/commander-2.18.0.tgz#2bf063ddee7c7891176981a2cc798e5754bc6970" integrity sha512-6CYPa+JP2ftfRU2qkDK+UTVeQYosOg/2GbcjIcKPHfinyOLPVGXu/ovN86RP49Re5ndJK1N0kuiidFFuepc4ZQ== -commander@^2.11.0: - version "2.20.3" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" - integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== - commander@~2.8.1: version "2.8.1" resolved "https://registry.yarnpkg.com/commander/-/commander-2.8.1.tgz#06be367febfda0c330aa1e2a072d3dc9762425d4" @@ -1790,11 +1760,6 @@ concat-stream@^1.5.1, concat-stream@^1.6.0: readable-stream "^2.2.2" typedarray "^0.0.6" -confusing-browser-globals@^1.0.7: - version "1.0.9" - resolved "https://registry.yarnpkg.com/confusing-browser-globals/-/confusing-browser-globals-1.0.9.tgz#72bc13b483c0276801681871d4898516f8f54fdd" - integrity sha512-KbS1Y0jMtyPgIxjO7ZzMAuUpAKMt1SzCL9fsrKsX6b0zJPTaT0SiSPmewwVZg9UAO83HVIlEhZF84LIjZ0lmAw== - contains-path@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/contains-path/-/contains-path-0.1.0.tgz#fe8cf184ff6670b6baef01a9d4861a5cbec4120a" @@ -1847,7 +1812,7 @@ copy-props@^2.0.1: each-props "^1.3.0" is-plain-object "^2.0.1" -core-js-pure@^3.0.0, core-js-pure@^3.0.1: +core-js-pure@^3.0.1: version "3.6.4" resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.6.4.tgz#4bf1ba866e25814f149d4e9aaa08c36173506e3a" integrity sha512-epIhRLkXdgv32xIUFaaAry2wdxZYBi6bgM7cB136dzzXXa+dFyRLTZeLUJxnd8ShrmyVXBub63n2NHo2JAt8Cw== @@ -1910,7 +1875,7 @@ create-hash@^1.1.0, create-hash@^1.1.1, create-hash@^1.1.2, create-hash@^1.2.0: ripemd160 "^2.0.1" sha.js "^2.4.0" -create-hmac@^1.1.0, create-hmac@^1.1.2, create-hmac@^1.1.4: +create-hmac@^1.1.0, create-hmac@^1.1.2, create-hmac@^1.1.4, create-hmac@^1.1.7: version "1.1.7" resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.7.tgz#69170c78b3ab957147b2b8b04572e47ead2243ff" integrity sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg== @@ -1966,11 +1931,6 @@ d@1, d@^1.0.1: es5-ext "^0.10.50" type "^1.0.1" -damerau-levenshtein@^1.0.4: - version "1.0.5" - resolved "https://registry.yarnpkg.com/damerau-levenshtein/-/damerau-levenshtein-1.0.5.tgz#780cf7144eb2e8dbd1c3bb83ae31100ccc31a414" - integrity sha512-CBCRqFnpu715iPmw1KrdOrzRqbdFwQTwAWyyyYS42+iAgHCuXZ+/TdMgQkUENPomxEz9z1BEzuQU2Xw0kUuAgA== - dashdash@^1.12.0: version "1.14.1" resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" @@ -2377,7 +2337,7 @@ elliptic@^6.0.0, elliptic@^6.4.0, elliptic@^6.5.2: minimalistic-assert "^1.0.0" minimalistic-crypto-utils "^1.0.0" -emoji-regex@^7.0.1, emoji-regex@^7.0.2: +emoji-regex@^7.0.1: version "7.0.3" resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA== @@ -2515,24 +2475,6 @@ escodegen@1.8.x: optionalDependencies: source-map "~0.2.0" -eslint-config-airbnb-base@^14.0.0: - version "14.0.0" - resolved "https://registry.yarnpkg.com/eslint-config-airbnb-base/-/eslint-config-airbnb-base-14.0.0.tgz#8a7bcb9643d13c55df4dd7444f138bf4efa61e17" - integrity sha512-2IDHobw97upExLmsebhtfoD3NAKhV4H0CJWP3Uprd/uk+cHuWYOczPVxQ8PxLFUAw7o3Th1RAU8u1DoUpr+cMA== - dependencies: - confusing-browser-globals "^1.0.7" - object.assign "^4.1.0" - object.entries "^1.1.0" - -eslint-config-airbnb@^18.0.1: - version "18.0.1" - resolved "https://registry.yarnpkg.com/eslint-config-airbnb/-/eslint-config-airbnb-18.0.1.tgz#a3a74cc29b46413b6096965025381df8fb908559" - integrity sha512-hLb/ccvW4grVhvd6CT83bECacc+s4Z3/AEyWQdIT2KeTsG9dR7nx1gs7Iw4tDmGKozCNHFn4yZmRm3Tgy+XxyQ== - dependencies: - eslint-config-airbnb-base "^14.0.0" - object.assign "^4.1.0" - object.entries "^1.1.0" - eslint-config-standard-jsx@8.1.0: version "8.1.0" resolved "https://registry.yarnpkg.com/eslint-config-standard-jsx/-/eslint-config-standard-jsx-8.1.0.tgz#314c62a0e6f51f75547f89aade059bec140edfc7" @@ -2551,7 +2493,7 @@ eslint-import-resolver-node@^0.3.2: debug "^2.6.9" resolve "^1.13.1" -eslint-module-utils@^2.4.0, eslint-module-utils@^2.4.1: +eslint-module-utils@^2.4.0: version "2.5.2" resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.5.2.tgz#7878f7504824e1b857dd2505b59a8e5eda26a708" integrity sha512-LGScZ/JSlqGKiT8OC+cYRxseMjyqt6QO54nl281CK93unD89ijSeRV6An8Ci/2nvWVKe8K/Tqdm75RQoIOCr+Q== @@ -2567,24 +2509,6 @@ eslint-plugin-es@^2.0.0: eslint-utils "^1.4.2" regexpp "^3.0.0" -eslint-plugin-import@^2.18.2: - version "2.20.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.20.0.tgz#d749a7263fb6c29980def8e960d380a6aa6aecaa" - integrity sha512-NK42oA0mUc8Ngn4kONOPsPB1XhbUvNHqF+g307dPV28aknPoiNnKLFd9em4nkswwepdF5ouieqv5Th/63U7YJQ== - dependencies: - array-includes "^3.0.3" - array.prototype.flat "^1.2.1" - contains-path "^0.1.0" - debug "^2.6.9" - doctrine "1.5.0" - eslint-import-resolver-node "^0.3.2" - eslint-module-utils "^2.4.1" - has "^1.0.3" - minimatch "^3.0.4" - object.values "^1.1.0" - read-pkg-up "^2.0.0" - resolve "^1.12.0" - eslint-plugin-import@~2.18.0: version "2.18.2" resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.18.2.tgz#02f1180b90b077b33d447a17a2326ceb400aceb6" @@ -2602,21 +2526,6 @@ eslint-plugin-import@~2.18.0: read-pkg-up "^2.0.0" resolve "^1.11.0" -eslint-plugin-jsx-a11y@^6.2.3: - version "6.2.3" - resolved "https://registry.yarnpkg.com/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.2.3.tgz#b872a09d5de51af70a97db1eea7dc933043708aa" - integrity sha512-CawzfGt9w83tyuVekn0GDPU9ytYtxyxyFZ3aSWROmnRRFQFT2BiPJd7jvRdzNDi6oLWaS2asMeYSNMjWTV4eNg== - dependencies: - "@babel/runtime" "^7.4.5" - aria-query "^3.0.0" - array-includes "^3.0.3" - ast-types-flow "^0.0.7" - axobject-query "^2.0.2" - damerau-levenshtein "^1.0.4" - emoji-regex "^7.0.2" - has "^1.0.3" - jsx-ast-utils "^2.2.1" - eslint-plugin-node@~10.0.0: version "10.0.0" resolved "https://registry.yarnpkg.com/eslint-plugin-node/-/eslint-plugin-node-10.0.0.tgz#fd1adbc7a300cf7eb6ac55cf4b0b6fc6e577f5a6" @@ -2634,21 +2543,6 @@ eslint-plugin-promise@~4.2.1: resolved "https://registry.yarnpkg.com/eslint-plugin-promise/-/eslint-plugin-promise-4.2.1.tgz#845fd8b2260ad8f82564c1222fce44ad71d9418a" integrity sha512-VoM09vT7bfA7D+upt+FjeBO5eHIJQBUWki1aPvB+vbNiHS3+oGIJGIeyBtKQTME6UPXXy3vV07OL1tHd3ANuDw== -eslint-plugin-react@^7.17.0: - version "7.18.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.18.0.tgz#2317831284d005b30aff8afb7c4e906f13fa8e7e" - integrity sha512-p+PGoGeV4SaZRDsXqdj9OWcOrOpZn8gXoGPcIQTzo2IDMbAKhNDnME9myZWqO3Ic4R3YmwAZ1lDjWl2R2hMUVQ== - dependencies: - array-includes "^3.1.1" - doctrine "^2.1.0" - has "^1.0.3" - jsx-ast-utils "^2.2.3" - object.entries "^1.1.1" - object.fromentries "^2.0.2" - object.values "^1.1.1" - prop-types "^15.7.2" - resolve "^1.14.2" - eslint-plugin-react@~7.14.2: version "7.14.3" resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.14.3.tgz#911030dd7e98ba49e1b2208599571846a66bdf13" @@ -3043,6 +2937,27 @@ ethereum-common@^0.0.18: resolved "https://registry.yarnpkg.com/ethereum-common/-/ethereum-common-0.0.18.tgz#2fdc3576f232903358976eb39da783213ff9523f" integrity sha1-L9w1dvIykDNYl26znaeDIT/5Uj8= +ethereum-cryptography@^0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz#8d6143cfc3d74bf79bbd8edecdf29e4ae20dd191" + integrity sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ== + dependencies: + "@types/pbkdf2" "^3.0.0" + "@types/secp256k1" "^4.0.1" + blakejs "^1.1.0" + browserify-aes "^1.2.0" + bs58check "^2.1.2" + create-hash "^1.2.0" + create-hmac "^1.1.7" + hash.js "^1.1.7" + keccak "^3.0.0" + pbkdf2 "^3.0.17" + randombytes "^2.1.0" + safe-buffer "^5.1.2" + scrypt-js "^3.0.0" + secp256k1 "^4.0.1" + setimmediate "^1.0.5" + ethereumjs-abi@0.6.5: version "0.6.5" resolved "https://registry.yarnpkg.com/ethereumjs-abi/-/ethereumjs-abi-0.6.5.tgz#5a637ef16ab43473fa72a29ad90871405b3f5241" @@ -3180,6 +3095,19 @@ ethereumjs-util@6.1.0, ethereumjs-util@~6.1.0: safe-buffer "^5.1.1" secp256k1 "^3.0.1" +ethereumjs-util@6.2.1: + version "6.2.1" + resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz#fcb4e4dd5ceacb9d2305426ab1a5cd93e3163b69" + integrity sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw== + dependencies: + "@types/bn.js" "^4.11.3" + bn.js "^4.11.0" + create-hash "^1.1.2" + elliptic "^6.5.2" + ethereum-cryptography "^0.1.3" + ethjs-util "0.1.6" + rlp "^2.2.3" + ethereumjs-util@^4.0.1, ethereumjs-util@^4.3.0: version "4.5.0" resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-4.5.0.tgz#3e9428b317eebda3d7260d854fddda954b1f1bc6" @@ -3822,12 +3750,12 @@ ganache-cli@6.9.0: source-map-support "0.5.12" yargs "13.2.4" -ganache-cli@^6.7.0: - version "6.8.2" - resolved "https://registry.yarnpkg.com/ganache-cli/-/ganache-cli-6.8.2.tgz#357b5ea93f013a7f0fce4ede1b8bec8613e95dd3" - integrity sha512-FgsJx/hHh7A1/fmSQpNT5jxZ3dYEal4zQMqYyA8Bm7S6MgrVO48hIjnROn2JteubHY8Rob8LzxMkhEvoQce7WA== +ganache-cli@^6.12.1: + version "6.12.1" + resolved "https://registry.yarnpkg.com/ganache-cli/-/ganache-cli-6.12.1.tgz#148cf6541494ef1691bd68a77e4414981910cb3e" + integrity sha512-zoefZLQpQyEJH9jgtVYgM+ENFLAC9iwys07IDCsju2Ieq9KSTLH89RxSP4bhizXKV/h/+qaWpfyCBGWnBfqgIQ== dependencies: - ethereumjs-util "6.1.0" + ethereumjs-util "6.2.1" source-map-support "0.5.12" yargs "13.2.4" @@ -4330,7 +4258,7 @@ hash.js@1.1.3: inherits "^2.0.3" minimalistic-assert "^1.0.0" -hash.js@^1.0.0, hash.js@^1.0.3: +hash.js@^1.0.0, hash.js@^1.0.3, hash.js@^1.1.7: version "1.1.7" resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42" integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA== @@ -5047,7 +4975,7 @@ jsprim@^1.2.2: json-schema "0.2.3" verror "1.10.0" -jsx-ast-utils@^2.1.0, jsx-ast-utils@^2.2.1, jsx-ast-utils@^2.2.3: +jsx-ast-utils@^2.1.0: version "2.2.3" resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-2.2.3.tgz#8a9364e402448a3ce7f14d357738310d9248054f" integrity sha512-EdIHFMm+1BPynpKOpdPqiOsvnIrInRGJD7bzPZdPkjitQEqpdpUuFpq4T0npZFKTiB3RhWFdGN+oqOJIdhDhQA== @@ -5080,6 +5008,14 @@ keccak@^2.0.0: nan "^2.14.0" safe-buffer "^5.2.0" +keccak@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/keccak/-/keccak-3.0.1.tgz#ae30a0e94dbe43414f741375cff6d64c8bea0bff" + integrity sha512-epq90L9jlFWCW7+pQa6JOnKn2Xgl2mtI664seYR6MHskvI9agt7AnDqmAlp9TqU4/caMYbA08Hi5DMZAl5zdkA== + dependencies: + node-addon-api "^2.0.0" + node-gyp-build "^4.2.0" + keccakjs@^0.2.0: version "0.2.3" resolved "https://registry.yarnpkg.com/keccakjs/-/keccakjs-0.2.3.tgz#5e4e969ce39689a3861f445d7752ee3477f9fe72" @@ -5854,6 +5790,11 @@ nice-try@^1.0.4: resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== +node-addon-api@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-2.0.2.tgz#432cfa82962ce494b132e9d72a15b29f71ff5d32" + integrity sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA== + node-emoji@^1.10.0: version "1.10.0" resolved "https://registry.yarnpkg.com/node-emoji/-/node-emoji-1.10.0.tgz#8886abd25d9c7bb61802a658523d1f8d2a89b2da" @@ -5882,6 +5823,11 @@ node-fetch@~1.7.1: encoding "^0.1.11" is-stream "^1.0.1" +node-gyp-build@^4.2.0: + version "4.2.3" + resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.2.3.tgz#ce6277f853835f718829efb47db20f3e4d9c4739" + integrity sha512-MN6ZpzmfNCRM+3t57PTJHgHyw/h4OWnZ6mR8P5j/uZtqQr46RRuDE/P+g3n0YR/AiYXeWixZZzaip77gdICfRg== + nopt@3.x: version "3.0.6" resolved "https://registry.yarnpkg.com/nopt/-/nopt-3.0.6.tgz#c6465dbf08abcd4db359317f79ac68a646b28ff9" @@ -6009,7 +5955,7 @@ object.defaults@^1.0.0, object.defaults@^1.1.0: for-own "^1.0.0" isobject "^3.0.0" -object.entries@^1.1.0, object.entries@^1.1.1: +object.entries@^1.1.0: version "1.1.1" resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.1.1.tgz#ee1cf04153de02bb093fec33683900f57ce5399b" integrity sha512-ilqR7BgdyZetJutmDPfXCDffGa0/Yzl2ivVNpbx/g4UeWrCdRnFDUBrKJGLhGieRHDATnyZXWBeCb29k9CJysQ== @@ -6019,7 +5965,7 @@ object.entries@^1.1.0, object.entries@^1.1.1: function-bind "^1.1.1" has "^1.0.3" -object.fromentries@^2.0.0, object.fromentries@^2.0.2: +object.fromentries@^2.0.0: version "2.0.2" resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.2.tgz#4a09c9b9bb3843dd0f89acdb517a794d4f355ac9" integrity sha512-r3ZiBH7MQppDJVLx6fhD618GKNG40CZYH9wgwdhKxBDDbQgjeWGGd4AtkZad84d291YxvWe7bJGuE65Anh0dxQ== @@ -6060,7 +6006,7 @@ object.reduce@^1.0.0: for-own "^1.0.0" make-iterator "^1.0.0" -object.values@^1.1.0, object.values@^1.1.1: +object.values@^1.1.0: version "1.1.1" resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.1.tgz#68a99ecde356b7e9295a3c5e0ce31dc8c953de5e" integrity sha512-WTa54g2K8iu0kmS/us18jEmdv1a4Wi//BZ/DTVYEcH0XhLM5NYdpDHja3gt57VrZLcNAO2WGA+KpWsDBaHt6eA== @@ -6373,6 +6319,17 @@ pathval@^1.1.0: resolved "https://registry.yarnpkg.com/pathval/-/pathval-1.1.0.tgz#b942e6d4bde653005ef6b71361def8727d0645e0" integrity sha1-uULm1L3mUwBe9rcTYd74cn0GReA= +pbkdf2@^3.0.17: + version "3.1.1" + resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.1.1.tgz#cb8724b0fada984596856d1a6ebafd3584654b94" + integrity sha512-4Ejy1OPxi9f2tt1rRV7Go7zmfDQ+ZectEQz3VGUQhgq62HtIRPDyG/JtnwIxs6x3uNMwo2V7q1fMvKjb+Tnpqg== + dependencies: + create-hash "^1.1.2" + create-hmac "^1.1.4" + ripemd160 "^2.0.1" + safe-buffer "^5.0.1" + sha.js "^2.4.8" + pbkdf2@^3.0.3, pbkdf2@^3.0.9: version "3.0.17" resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.0.17.tgz#976c206530617b14ebb32114239f7b09336e93a6" @@ -6809,11 +6766,6 @@ regenerator-runtime@^0.11.0: resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9" integrity sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg== -regenerator-runtime@^0.13.2: - version "0.13.3" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.3.tgz#7cf6a77d8f5c6f60eb73c5fc1955b2ceb01e6bf5" - integrity sha512-naKIZz2GQ8JWh///G7L3X6LaQUAMp2lvb1rvwwsURe/VXwD6VMfr+/1NuNw3ag8v2kY1aQ/go5SNn79O9JU7yw== - regenerator-transform@^0.10.0: version "0.10.1" resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.10.1.tgz#1e4996837231da8b7f3cf4114d71b5691a0680dd" @@ -6999,7 +6951,7 @@ resolve@1.1.x: resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" integrity sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs= -resolve@^1.1.6, resolve@^1.1.7, resolve@^1.10.0, resolve@^1.10.1, resolve@^1.11.0, resolve@^1.12.0, resolve@^1.13.1, resolve@^1.14.2, resolve@^1.4.0, resolve@~1.14.2: +resolve@^1.1.6, resolve@^1.1.7, resolve@^1.10.0, resolve@^1.10.1, resolve@^1.11.0, resolve@^1.13.1, resolve@^1.4.0, resolve@~1.14.2: version "1.14.2" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.14.2.tgz#dbf31d0fa98b1f29aa5169783b9c290cb865fea2" integrity sha512-EjlOBLBO1kxsUxsKjLt7TAECyKW6fOh1VRkykQkKGzcBbjjPIxBqGh0jf7GJ3k/f5mxMqW3htMD3WdTUVtW8HQ== @@ -7158,6 +7110,11 @@ scrypt-js@2.0.4: resolved "https://registry.yarnpkg.com/scrypt-js/-/scrypt-js-2.0.4.tgz#32f8c5149f0797672e551c07e230f834b6af5f16" integrity sha512-4KsaGcPnuhtCZQCxFxN3GVYIhKFPTdLd8PLC552XwbMndtD0cjRFAhDuuydXQ0h08ZfPgzqe6EKHozpuH74iDw== +scrypt-js@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/scrypt-js/-/scrypt-js-3.0.1.tgz#d314a57c2aef69d1ad98a138a21fe9eafa9ee312" + integrity sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA== + "scrypt-shim@github:web3-js/scrypt-shim": version "0.1.0" resolved "https://codeload.github.com/web3-js/scrypt-shim/tar.gz/aafdadda13e660e25e1c525d1f5b2443f5eb1ebb" @@ -7207,6 +7164,15 @@ secp256k1@^3.0.1: nan "^2.14.0" safe-buffer "^5.1.2" +secp256k1@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/secp256k1/-/secp256k1-4.0.2.tgz#15dd57d0f0b9fdb54ac1fa1694f40e5e9a54f4a1" + integrity sha512-UDar4sKvWAksIlfX3xIaQReADn+WFnHvbVujpcbr+9Sf/69odMwy2MUsz5CKLQgX9nsIyrjuxL2imVyoNHa3fg== + dependencies: + elliptic "^6.5.2" + node-addon-api "^2.0.0" + node-gyp-build "^4.2.0" + seedrandom@3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/seedrandom/-/seedrandom-3.0.1.tgz#eb3dde015bcf55df05a233514e5df44ef9dce083"