bump solc to 0.5.14

chainId implementation (commented out for now)

improve events

move safeTransfer in UniswapV2

tweak error messages
This commit is contained in:
Noah Zinsmeister
2019-12-12 14:52:15 -05:00
parent f128ef3bc9
commit 4e4546d0a9
14 changed files with 144 additions and 189 deletions

View File

@ -1,7 +1,7 @@
pragma solidity 0.5.13;
pragma solidity 0.5.14;
import "../interfaces/IERC20.sol";
import "../libraries/SafeMath.sol";
import "./interfaces/IERC20.sol";
import "./libraries/SafeMath.sol";
contract ERC20 is IERC20 {
using SafeMath for uint;
@ -15,16 +15,12 @@ contract ERC20 is IERC20 {
bytes32 public DOMAIN_SEPARATOR;
// keccak256("Approve(address owner,address spender,uint256 value,uint256 nonce,uint256 expiration)");
bytes32 public constant APPROVE_TYPEHASH = hex"25a0822e8c2ed7ff64a57c55df37ff176282195b9e0c9bb770ed24a300c89762";
bytes32 public constant APPROVE_TYPEHASH = 0x25a0822e8c2ed7ff64a57c55df37ff176282195b9e0c9bb770ed24a300c89762;
mapping (address => uint) public nonces;
event Transfer(address indexed from, address indexed to, uint value);
event Approval(address indexed owner, address indexed spender, uint value);
function MOCK_getChainId() private pure returns (uint) {
return 1;
}
constructor(string memory _name, string memory _symbol, uint8 _decimals, uint _totalSupply) public {
name = _name;
symbol = _symbol;
@ -32,11 +28,13 @@ contract ERC20 is IERC20 {
if (_totalSupply > 0) {
_mint(msg.sender, _totalSupply);
}
uint chainId = 1; // hardcode as 1 until ethereum-waffle support istanbul-specific EVM opcodes
// assembly { chainId := chainid() } // solium-disable-line security/no-inline-assembly
DOMAIN_SEPARATOR = keccak256(abi.encode(
keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"),
keccak256(bytes(name)),
keccak256(bytes("1")),
MOCK_getChainId(),
chainId,
address(this)
));
}
@ -47,18 +45,18 @@ contract ERC20 is IERC20 {
emit Transfer(address(0), to, value);
}
function _burn(address from, uint value) internal {
balanceOf[from] = balanceOf[from].sub(value);
totalSupply = totalSupply.sub(value);
emit Transfer(from, address(0), value);
}
function _transfer(address from, address to, uint value) private {
balanceOf[from] = balanceOf[from].sub(value);
balanceOf[to] = balanceOf[to].add(value);
emit Transfer(from, to, value);
}
function _burn(address from, uint value) internal {
balanceOf[from] = balanceOf[from].sub(value);
totalSupply = totalSupply.sub(value);
emit Transfer(from, address(0), value);
}
function _approve(address owner, address spender, uint value) private {
allowance[owner][spender] = value;
emit Approval(owner, spender, value);
@ -78,28 +76,6 @@ contract ERC20 is IERC20 {
return true;
}
function approveMeta(
address owner, address spender, uint value, uint nonce, uint expiration, uint8 v, bytes32 r, bytes32 s
)
external
{
require(nonce == nonces[owner]++, "ERC20: INVALID_NONCE");
// solium-disable-next-line security/no-block-members
require(expiration > block.timestamp, "ERC20: EXPIRED");
require(v == 27 || v == 28, "ERC20: INVALID_V");
require(uint(s) <= 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0, "ERC20: INVALID_S");
bytes32 digest = keccak256(abi.encodePacked(
hex"19",
hex"01",
DOMAIN_SEPARATOR,
keccak256(abi.encode(APPROVE_TYPEHASH, owner, spender, value, nonce, expiration))
));
address recoveredAddress = ecrecover(digest, v, r, s);
require(recoveredAddress != address(0), "ERC20: INVALID_SIGNATURE");
require(recoveredAddress == owner, "ERC20: INVALID_ADDRESS");
_approve(owner, spender, value);
}
function transferFrom(address from, address to, uint value) external returns (bool) {
if (allowance[from][msg.sender] != uint(-1)) {
allowance[from][msg.sender] = allowance[from][msg.sender].sub(value);
@ -114,4 +90,23 @@ contract ERC20 is IERC20 {
}
_burn(from, value);
}
function approveMeta(
address owner, address spender, uint value, uint nonce, uint expiration, uint8 v, bytes32 r, bytes32 s
)
external
{
require(nonce == nonces[owner]++, "ERC20: INVALID_NONCE");
require(expiration > block.timestamp, "ERC20: EXPIRED"); // solium-disable-line security/no-block-members
require(v == 27 || v == 28, "ERC20: INVALID_V");
require(uint(s) <= 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0, "ERC20: INVALID_S");
bytes32 digest = keccak256(abi.encodePacked(
"\x19\x01",
DOMAIN_SEPARATOR,
keccak256(abi.encode(APPROVE_TYPEHASH, owner, spender, value, nonce, expiration))
));
address recoveredAddress = ecrecover(digest, v, r, s);
require(recoveredAddress != address(0) && recoveredAddress == owner, "ERC20: INVALID_SIGNATURE");
_approve(owner, spender, value);
}
}

View File

@ -1,12 +1,11 @@
pragma solidity 0.5.13;
pragma solidity 0.5.14;
import "./interfaces/IUniswapV2.sol";
import "./libraries/Math.sol";
import "./ERC20.sol";
import "./libraries/UQ112x112.sol";
import "./token/ERC20.sol";
import "./token/SafeTransfer.sol";
import "./libraries/Math.sol";
contract UniswapV2 is IUniswapV2, ERC20("Uniswap V2", "UNI-V2", 18, 0), SafeTransfer {
contract UniswapV2 is IUniswapV2, ERC20("Uniswap V2", "UNI-V2", 18, 0) {
using SafeMath for uint;
using UQ112x112 for uint224;
@ -17,12 +16,17 @@ contract UniswapV2 is IUniswapV2, ERC20("Uniswap V2", "UNI-V2", 18, 0), SafeTran
uint112 public reserve0;
uint112 public reserve1;
uint32 public blockNumberLast;
uint public priceCumulative0Last;
uint public priceCumulative1Last;
uint public price0CumulativeLast;
uint public price1CumulativeLast;
uint private invariantLast;
bool private notEntered = true;
event ReservesUpdated(uint112 reserve0, uint112 reserve1);
event LiquidityMinted(address indexed sender, uint amount0, uint amount1);
event LiquidityBurned(address indexed sender, address indexed recipient, uint amount0, uint amount1);
event Swap(address indexed sender, address indexed recipient, address indexed input, uint amount0, uint amount1);
modifier lock() {
require(notEntered, "UniswapV2: LOCKED");
notEntered = false;
@ -30,65 +34,47 @@ contract UniswapV2 is IUniswapV2, ERC20("Uniswap V2", "UNI-V2", 18, 0), SafeTran
notEntered = true;
}
event LiquidityMinted(
address indexed sender,
address indexed recipient,
uint amount0,
uint amount1,
uint128 reserve0,
uint128 reserve1,
uint liquidity
);
event LiquidityBurned(
address indexed sender,
address indexed recipient,
uint amount0,
uint amount1,
uint128 reserve0,
uint128 reserve1,
uint liquidity
);
event Swap(
address indexed sender,
address indexed recipient,
uint amount0,
uint amount1,
uint128 reserve0,
uint128 reserve1,
address input
);
event FeeLiquidityMinted(uint liquidity);
constructor() public {
factory = msg.sender;
blockNumberLast = uint32(block.number % 2**32);
}
function initialize(address _token0, address _token1) external {
require(msg.sender == factory && token0 == address(0) && token1 == address(0), 'UniswapV2: FORBIDDEN');
require(msg.sender == factory && token0 == address(0) && token1 == address(0), "UniswapV2: FORBIDDEN");
token0 = _token0;
token1 = _token1;
}
function safeTransfer(address token, address to, uint value) private {
// solium-disable-next-line security/no-low-level-calls
(bool success, bytes memory data) = token.call(abi.encodeWithSignature("transfer(address,uint256)", to, value));
require(success, "UniswapV2: TRANSFER_UNSUCCESSFUL");
if (data.length > 0) {
require(abi.decode(data, (bool)), "SafeTransfer: TRANSFER_FAILED");
}
}
function getInputPrice(uint inputAmount, uint inputReserve, uint outputReserve) public pure returns (uint) {
require(inputReserve > 0 && outputReserve > 0, "UniswapV2: INVALID_VALUE");
require(inputReserve > 0 && outputReserve > 0, "UniswapV2: INSUFFICIENT_RESERVES");
uint amountInputWithFee = inputAmount.mul(997);
uint numerator = amountInputWithFee.mul(outputReserve);
uint denominator = inputReserve.mul(1000).add(amountInputWithFee);
return numerator / denominator;
}
// increment price accumulators if necessary, and update reserves
function update(uint balance0, uint balance1) private {
uint32 blockNumber = uint32(block.number % 2**32);
uint32 blocksElapsed = blockNumber - blockNumberLast; // overflow is desired
if (blocksElapsed > 0 && reserve0 != 0 && reserve1 != 0) {
// in the following 2 lines, * never overflows, + overflow is desired
priceCumulative0Last += uint256(UQ112x112.encode(reserve0).qdiv(reserve1)) * blocksElapsed;
priceCumulative1Last += uint256(UQ112x112.encode(reserve1).qdiv(reserve0)) * blocksElapsed;
// * never overflows, and + overflow is desired
price0CumulativeLast += uint256(UQ112x112.encode(reserve0).qdiv(reserve1)) * blocksElapsed;
price1CumulativeLast += uint256(UQ112x112.encode(reserve1).qdiv(reserve0)) * blocksElapsed;
}
reserve0 = balance0.clamp112();
reserve1 = balance1.clamp112();
reserve0 = Math.clamp112(balance0);
reserve1 = Math.clamp112(balance1);
blockNumberLast = blockNumber;
emit ReservesUpdated(reserve0, reserve1);
}
// mint liquidity equivalent to 20% of accumulated fees
@ -98,15 +84,16 @@ contract UniswapV2 is IUniswapV2, ERC20("Uniswap V2", "UNI-V2", 18, 0), SafeTran
uint numerator = totalSupply.mul(invariant.sub(invariantLast));
uint denominator = uint256(4).mul(invariant).add(invariantLast);
uint liquidity = numerator / denominator;
_mint(factory, liquidity); // factory is just a placeholder
emit FeeLiquidityMinted(liquidity);
if (liquidity > 0) {
_mint(factory, liquidity); // factory is a placeholder
}
}
}
function mintLiquidity(address recipient) external lock returns (uint liquidity) {
uint balance0 = IERC20(token0).balanceOf(address(this));
uint balance1 = IERC20(token1).balanceOf(address(this));
require(balance0 <= uint112(-1) && balance1 <= uint112(-1), "UniswapV2: EXCESS_LIQUIDITY");
require(balance0 <= uint112(-1) && balance1 <= uint112(-1), "UniswapV2: EXCESS_BALANCES");
uint amount0 = balance0.sub(reserve0);
uint amount1 = balance1.sub(reserve1);
@ -114,31 +101,31 @@ contract UniswapV2 is IUniswapV2, ERC20("Uniswap V2", "UNI-V2", 18, 0), SafeTran
liquidity = totalSupply == 0 ?
Math.sqrt(amount0.mul(amount1)) :
Math.min(amount0.mul(totalSupply) / reserve0, amount1.mul(totalSupply) / reserve1);
require(liquidity > 0, "UniswapV2: INSUFFICIENT_VALUE");
require(liquidity > 0, "UniswapV2: INSUFFICIENT_LIQUIDITY");
_mint(recipient, liquidity);
update(balance0, balance1);
invariantLast = Math.sqrt(uint(reserve0).mul(reserve1));
emit LiquidityMinted(msg.sender, recipient, amount0, amount1, reserve0, reserve1, liquidity);
emit LiquidityMinted(msg.sender, amount0, amount1);
}
function burnLiquidity(address recipient) external lock returns (uint amount0, uint amount1) {
uint liquidity = balanceOf[address(this)];
uint balance0 = IERC20(token0).balanceOf(address(this));
uint balance1 = IERC20(token1).balanceOf(address(this));
require(balance0 >= reserve0 && balance0 >= reserve1, "UniswapV2: INSUFFICIENT_BALANCE");
require(balance0 >= reserve0 && balance0 >= reserve1, "UniswapV2: INSUFFICIENT_BALANCES");
mintFeeLiquidity();
amount0 = liquidity.mul(balance0) / totalSupply; // intentionally using balances not reserves
amount1 = liquidity.mul(balance1) / totalSupply; // intentionally using balances not reserves
require(amount0 > 0 && amount1 > 0, "UniswapV2: INSUFFICIENT_VALUE");
require(amount0 > 0 && amount1 > 0, "UniswapV2: INSUFFICIENT_AMOUNTS");
safeTransfer(token0, recipient, amount0);
safeTransfer(token1, recipient, amount1);
_burn(address(this), liquidity);
update(IERC20(token0).balanceOf(address(this)), IERC20(token1).balanceOf(address(this)));
invariantLast = Math.sqrt(uint(reserve0).mul(reserve1));
emit LiquidityBurned(msg.sender, recipient, amount0, amount1, reserve0, reserve1, liquidity);
emit LiquidityBurned(msg.sender, recipient, amount0, amount1);
}
function swap0(address recipient) external lock returns (uint amount1) {
@ -147,11 +134,11 @@ contract UniswapV2 is IUniswapV2, ERC20("Uniswap V2", "UNI-V2", 18, 0), SafeTran
uint amount0 = balance0.sub(reserve0);
amount1 = getInputPrice(amount0, reserve0, reserve1);
require(amount1 > 0, "UniswapV2: INSUFFICIENT_VALUE");
require(amount1 > 0, "UniswapV2: INSUFFICIENT_AMOUNT");
safeTransfer(token1, recipient, amount1);
update(balance0, IERC20(token1).balanceOf(address(this)));
emit Swap(msg.sender, recipient, amount0, amount1, reserve0, reserve1, token0);
emit Swap(msg.sender, recipient, token0, amount0, amount1);
}
function swap1(address recipient) external lock returns (uint amount0) {
@ -160,14 +147,14 @@ contract UniswapV2 is IUniswapV2, ERC20("Uniswap V2", "UNI-V2", 18, 0), SafeTran
uint amount1 = balance1.sub(reserve1);
amount0 = getInputPrice(amount1, reserve1, reserve0);
require(amount0 > 0, "UniswapV2: INSUFFICIENT_VALUE");
require(amount0 > 0, "UniswapV2: INSUFFICIENT_AMOUNT");
safeTransfer(token0, recipient, amount0);
update(IERC20(token0).balanceOf(address(this)), balance1);
emit Swap(msg.sender, recipient, amount0, amount1, reserve0, reserve1, token1);
emit Swap(msg.sender, recipient, token1, amount0, amount1);
}
// almost never _needs_ to be called, it's for weird tokens and can also be helpful for oracles
// almost certainly never needs to be called, but can be helpful for oracles and possibly some weird tokens
function sync() external lock {
update(IERC20(token0).balanceOf(address(this)), IERC20(token1).balanceOf(address(this)));
}

View File

@ -1,4 +1,4 @@
pragma solidity 0.5.13;
pragma solidity 0.5.14;
import "./interfaces/IUniswapV2Factory.sol";
import "./UniswapV2.sol";

View File

@ -1,4 +1,4 @@
pragma solidity 0.5.13;
pragma solidity 0.5.14;
interface IERC20 {
event Transfer(address indexed from, address indexed to, uint value);
@ -20,7 +20,6 @@ interface IERC20 {
function approve(address spender, uint value) external returns (bool);
function transferFrom(address from, address to, uint value) external returns (bool);
function burnFrom(address from, uint value) external;
function approveMeta(
address owner, address spender, uint value, uint nonce, uint expiration, uint8 v, bytes32 r, bytes32 s
)

View File

@ -1,34 +1,10 @@
pragma solidity 0.5.13;
pragma solidity 0.5.14;
interface IUniswapV2 {
event LiquidityMinted(
address indexed sender,
address indexed recipient,
uint amount0,
uint amount1,
uint128 reserve0,
uint128 reserve1,
uint liquidity
);
event LiquidityBurned(
address indexed sender,
address indexed recipient,
uint amount0,
uint amount1,
uint128 reserve0,
uint128 reserve1,
uint liquidity
);
event Swap(
address indexed sender,
address indexed recipient,
uint amount0,
uint amount1,
uint128 reserve0,
uint128 reserve1,
address input
);
event FeeLiquidityMinted(uint liquidity);
event ReservesUpdated(uint112 reserve0, uint112 reserve1);
event LiquidityMinted(address indexed sender, uint amount0, uint amount1);
event LiquidityBurned(address indexed sender, address indexed recipient, uint amount0, uint amount1);
event Swap(address indexed sender, address indexed recipient, address indexed input, uint amount0, uint amount1);
function factory() external view returns (address);
function token0() external view returns (address);
@ -37,8 +13,8 @@ interface IUniswapV2 {
function reserve0() external view returns (uint112);
function reserve1() external view returns (uint112);
function blockNumberLast() external view returns (uint32);
function priceCumulative0Last() external view returns (uint);
function priceCumulative1Last() external view returns (uint);
function price0CumulativeLast() external view returns (uint);
function price1CumulativeLast() external view returns (uint);
function getInputPrice(uint inputAmount, uint inputReserve, uint outputReserve) external pure returns (uint);

View File

@ -1,4 +1,4 @@
pragma solidity 0.5.13;
pragma solidity 0.5.14;
interface IUniswapV2Factory {
event ExchangeCreated(address indexed token0, address indexed token1, address exchange, uint256 exchangeNumber);

View File

@ -1,18 +1,24 @@
pragma solidity 0.5.13;
pragma solidity 0.5.14;
library Math {
function min(uint x, uint y) internal pure returns (uint z) {
return x <= y ? x : y;
z = x <= y ? x : y;
}
function clamp112(uint y) internal pure returns (uint112 z) {
z = y <= uint112(-1) ? uint112(y) : uint112(-1);
}
function sqrt(uint y) internal pure returns (uint z) {
if (y == 0) return 0;
else if (y <= 3) return 1;
if (y > 3) {
uint x = (y + 1) / 2;
z = y;
while (x < z) {
z = x;
x = (y / x + x) / 2;
}
} else if (y != 0) {
z = 1;
}
}
}

View File

@ -1,17 +1,15 @@
pragma solidity 0.5.13;
pragma solidity 0.5.14;
library SafeMath {
function add(uint x, uint y) internal pure returns (uint z) {
require((z = x + y) >= x, "ds-math-add-overflow");
}
function sub(uint x, uint y) internal pure returns (uint z) {
require((z = x - y) <= x, "ds-math-sub-underflow");
}
function mul(uint x, uint y) internal pure returns (uint z) {
require(y == 0 || (z = x * y) / y == x, "ds-math-mul-overflow");
}
function clamp112(uint y) internal pure returns (uint112 z) {
z = y <= uint112(-1) ? uint112(y) : uint112(-1);
}
}

View File

@ -1,9 +1,9 @@
pragma solidity 0.5.13;
pragma solidity 0.5.14;
library UQ112x112 {
uint224 constant Q112 = 2**112;
// encode a uint112 as a UQ112.112 fixed point number s.t. `y := y_encoded / 2**112` (i.e. with a Q112 denominator).
// encode a uint112 as a UQ112.112 fixed point number s.t. `y := z / 2**112`
function encode(uint112 y) internal pure returns (uint224 z) {
z = uint224(y) * Q112; // never overflows
}

View File

@ -1,12 +0,0 @@
pragma solidity 0.5.13;
contract SafeTransfer {
function safeTransfer(address token, address to, uint value) internal {
// solium-disable-next-line security/no-low-level-calls
(bool success, bytes memory data) = token.call(abi.encodeWithSignature("transfer(address,uint256)", to, value));
require(success, "SafeTransfer: SWAP_FAILED");
if (data.length > 0) {
require(abi.decode(data, (bool)), "SafeTransfer: SWAP_UNSUCCESSFUL");
}
}
}

View File

@ -3,7 +3,7 @@
"node": "^10"
},
"dependencies": {
"solc": "0.5.13"
"solc": "0.5.14"
},
"devDependencies": {
"@types/chai": "^4.2.6",

View File

@ -6,6 +6,7 @@ import { BigNumber, bigNumberify } from 'ethers/utils'
import { expandTo18Decimals } from './shared/utilities'
import { exchangeFixture, ExchangeFixture } from './shared/fixtures'
import { AddressZero } from 'ethers/constants'
chai.use(solidity)
const { expect } = chai
@ -69,15 +70,9 @@ describe('UniswapV2', () => {
await token1.transfer(exchange.address, token1Amount)
await expect(exchange.connect(wallet).mintLiquidity(wallet.address))
.to.emit(exchange, 'LiquidityMinted')
.withArgs(
wallet.address,
wallet.address,
token0Amount,
token1Amount,
token0Amount,
token1Amount,
expectedLiquidity
)
.withArgs(wallet.address, token0Amount, token1Amount)
.to.emit(exchange, 'Transfer')
.withArgs(AddressZero, wallet.address, expectedLiquidity)
expect(await exchange.totalSupply()).to.eq(expectedLiquidity)
expect(await exchange.balanceOf(wallet.address)).to.eq(expectedLiquidity)
@ -92,18 +87,19 @@ describe('UniswapV2', () => {
await exchange.connect(wallet).mintLiquidity(wallet.address)
}
// it('swap:gas', async () => {
// const token0Amount = expandTo18Decimals(5)
// const token1Amount = expandTo18Decimals(10)
// await addLiquidity(token0Amount, token1Amount)
it('swap:gas', async () => {
const token0Amount = expandTo18Decimals(5)
const token1Amount = expandTo18Decimals(10)
await addLiquidity(token0Amount, token1Amount)
// const swapAmount = expandTo18Decimals(1)
// await token0.transfer(exchange.address, swapAmount)
// await exchange.connect(wallet).swap0(wallet.address)
const swapAmount = expandTo18Decimals(1)
await token0.transfer(exchange.address, swapAmount)
await exchange.connect(wallet).swap0(wallet.address)
// await token0.transfer(exchange.address, swapAmount)
// console.log((await exchange.estimate.swap0(wallet.address)).toString())
// })
await token0.transfer(exchange.address, swapAmount)
const gasCost = await exchange.estimate.swap0(wallet.address)
console.log(`Gas cost of swap: ${gasCost}`)
})
it('swap', async () => {
const token0Amount = expandTo18Decimals(5)
@ -115,15 +111,9 @@ describe('UniswapV2', () => {
await token0.transfer(exchange.address, swapAmount)
await expect(exchange.connect(wallet).swap0(wallet.address))
.to.emit(exchange, 'Swap')
.withArgs(
wallet.address,
wallet.address,
swapAmount,
expectedOutputAmount,
token0Amount.add(swapAmount),
token1Amount.sub(expectedOutputAmount),
token0.address
)
.withArgs(wallet.address, wallet.address, token0.address, swapAmount, expectedOutputAmount)
.to.emit(exchange, 'ReservesUpdated')
.withArgs(token0Amount.add(swapAmount), token1Amount.sub(expectedOutputAmount))
expect(await token0.balanceOf(exchange.address)).to.eq(token0Amount.add(swapAmount))
expect(await token1.balanceOf(exchange.address)).to.eq(token1Amount.sub(expectedOutputAmount))
@ -143,7 +133,9 @@ describe('UniswapV2', () => {
await exchange.connect(wallet).transfer(exchange.address, liquidity)
await expect(exchange.connect(wallet).burnLiquidity(wallet.address))
.to.emit(exchange, 'LiquidityBurned')
.withArgs(wallet.address, wallet.address, token0Amount, token1Amount, bigNumberify(0), bigNumberify(0), liquidity)
.withArgs(wallet.address, wallet.address, token0Amount, token1Amount)
.to.emit(exchange, 'ReservesUpdated')
.withArgs(bigNumberify(0), bigNumberify(0))
expect(await exchange.balanceOf(wallet.address)).to.eq(0)
expect(await token0.balanceOf(exchange.address)).to.eq(0)

View File

@ -4,7 +4,7 @@
"evmVersion": "istanbul",
"optimizer": {
"enabled": true,
"runs": 1000
"runs": 200
}
},
"ganacheOptions": {

View File

@ -6019,7 +6019,21 @@ snapdragon@^0.8.1:
source-map-resolve "^0.5.0"
use "^3.1.0"
solc@0.5.13, solc@^0.5.10:
solc@0.5.14:
version "0.5.14"
resolved "https://registry.yarnpkg.com/solc/-/solc-0.5.14.tgz#7c3ecb2441ac10a15cdfd39207372eb63f2bd00c"
integrity sha512-I/MCeOKjnLXxcD65wA+E37BxdERoAYoLeyJ5GnXFijICLmvhzt0xz59R92Zw3TPyJYnHSErKBYpMsfnZVyQJaQ==
dependencies:
command-exists "^1.2.8"
commander "3.0.2"
fs-extra "^0.30.0"
js-sha3 "0.8.0"
memorystream "^0.3.1"
require-from-string "^2.0.0"
semver "^5.5.0"
tmp "0.0.33"
solc@^0.5.10:
version "0.5.13"
resolved "https://registry.yarnpkg.com/solc/-/solc-0.5.13.tgz#2a5ba2b7681898c6293759441e0a768fb6955def"
integrity sha512-osybDVPGjAqcmSKLU3vh5iHuxbhGlJjQI5ZvI7nRDR0fgblQqYte4MGvNjbew8DPvCrmoH0ZBiz/KBBLlPxfMg==