Skip to content

Commit cbe801b

Browse files
remove forfeit{,from}
make name + symbol + decimals constant add GenericERC20 rename some contracts update tests to reflect all of this
1 parent 5a84023 commit cbe801b

11 files changed

+73
-93
lines changed

contracts/ERC20.sol renamed to contracts/UniswapV2ERC20.sol

Lines changed: 6 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
pragma solidity 0.5.15;
22

3-
import "./interfaces/IERC20.sol";
3+
import "./interfaces/IUniswapV2ERC20.sol";
44
import "./libraries/SafeMath.sol";
55

6-
contract ERC20 is IERC20 {
6+
contract UniswapV2ERC20 is IUniswapV2ERC20 {
77
using SafeMath for uint;
88

9-
string public name;
10-
string public symbol;
11-
uint8 public decimals;
9+
string constant public name = "Uniswap V2";
10+
string constant public symbol = "UNI-V2";
11+
uint8 constant public decimals = 18;
1212
uint public totalSupply;
1313
mapping (address => uint) public balanceOf;
1414
mapping (address => mapping (address => uint)) public allowance;
@@ -21,11 +21,7 @@ contract ERC20 is IERC20 {
2121
event Transfer(address indexed from, address indexed to, uint value);
2222
event Approval(address indexed owner, address indexed spender, uint value);
2323

24-
constructor(string memory _name, string memory _symbol, uint8 _decimals, uint _totalSupply) public {
25-
name = _name;
26-
symbol = _symbol;
27-
decimals = _decimals;
28-
if (_totalSupply > 0) _mint(msg.sender, _totalSupply);
24+
constructor() public {
2925
uint chainId;
3026
assembly { // solium-disable-line security/no-inline-assembly
3127
chainId := chainid()
@@ -67,10 +63,6 @@ contract ERC20 is IERC20 {
6763
return true;
6864
}
6965

70-
function forfeit(uint value) external {
71-
_burn(msg.sender, value);
72-
}
73-
7466
function approve(address spender, uint value) external returns (bool) {
7567
_approve(msg.sender, spender, value);
7668
return true;
@@ -84,13 +76,6 @@ contract ERC20 is IERC20 {
8476
return true;
8577
}
8678

87-
function forfeitFrom(address from, uint value) external {
88-
if (allowance[from][msg.sender] != uint(-1)) {
89-
allowance[from][msg.sender] = allowance[from][msg.sender].sub(value);
90-
}
91-
_burn(from, value);
92-
}
93-
9479
function permit(
9580
address owner, address spender, uint value, uint nonce, uint deadline, uint8 v, bytes32 r, bytes32 s
9681
)

contracts/UniswapV2.sol renamed to contracts/UniswapV2Exchange.sol

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
pragma solidity 0.5.15;
22

3-
import "./interfaces/IUniswapV2.sol";
4-
import "./ERC20.sol";
5-
import "./libraries/UQ112x112.sol";
3+
import "./interfaces/IUniswapV2Exchange.sol";
4+
import "./UniswapV2ERC20.sol";
65
import "./libraries/Math.sol";
6+
import "./libraries/UQ112x112.sol";
7+
import "./interfaces/IERC20.sol";
78
import "./interfaces/IUniswapV2Factory.sol";
89

9-
contract UniswapV2 is IUniswapV2, ERC20("Uniswap V2", "UNI-V2", 18, 0) {
10+
contract UniswapV2Exchange is IUniswapV2Exchange, UniswapV2ERC20 {
1011
using SafeMath for uint;
1112
using UQ112x112 for uint224;
1213

contracts/UniswapV2Factory.sol

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
pragma solidity 0.5.15;
22

33
import "./interfaces/IUniswapV2Factory.sol";
4-
import "./interfaces/IUniswapV2.sol";
5-
import "./UniswapV2.sol";
4+
import "./UniswapV2Exchange.sol";
5+
import "./interfaces/IUniswapV2Exchange.sol";
66

77
contract UniswapV2Factory is IUniswapV2Factory {
88
address public feeToSetter;
@@ -35,12 +35,12 @@ contract UniswapV2Factory is IUniswapV2Factory {
3535
require(tokenA != address(0) && tokenB != address(0), "UniswapV2Factory: ZERO_ADDRESS");
3636
(address token0, address token1) = sortTokens(tokenA, tokenB);
3737
require(getExchange_[token0][token1] == address(0), "UniswapV2Factory: EXCHANGE_EXISTS");
38-
bytes memory exchangeBytecode = type(UniswapV2).creationCode;
38+
bytes memory exchangeBytecode = type(UniswapV2Exchange).creationCode;
3939
bytes32 salt = keccak256(abi.encodePacked(token0, token1));
4040
assembly { // solium-disable-line security/no-inline-assembly
4141
exchange := create2(0, add(exchangeBytecode, 32), mload(exchangeBytecode), salt)
4242
}
43-
IUniswapV2(exchange).initialize(token0, token1);
43+
IUniswapV2Exchange(exchange).initialize(token0, token1);
4444
getExchange_[token0][token1] = exchange;
4545
exchanges.push(exchange);
4646
emit ExchangeCreated(token0, token1, exchange, exchanges.length);

contracts/interfaces/IERC20.sol

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,8 @@ interface IERC20 {
1010
function totalSupply() external view returns (uint);
1111
function balanceOf(address owner) external view returns (uint);
1212
function allowance(address owner, address spender) external view returns (uint);
13-
function DOMAIN_SEPARATOR() external view returns (bytes32);
14-
function PERMIT_TYPEHASH() external pure returns (bytes32);
15-
function nonces(address owner) external view returns (uint);
1613

1714
function transfer(address to, uint value) external returns (bool);
18-
function forfeit(uint value) external;
1915
function approve(address spender, uint value) external returns (bool);
2016
function transferFrom(address from, address to, uint value) external returns (bool);
21-
function forfeitFrom(address from, uint value) external;
22-
function permit(
23-
address owner, address spender, uint value, uint nonce, uint expiration, uint8 v, bytes32 r, bytes32 s
24-
)
25-
external;
2617
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
pragma solidity 0.5.15;
2+
3+
interface IUniswapV2ERC20 {
4+
event Transfer(address indexed from, address indexed to, uint value);
5+
event Approval(address indexed owner, address indexed spender, uint value);
6+
7+
function name() external view returns (string memory);
8+
function symbol() external view returns (string memory);
9+
function decimals() external view returns (uint8);
10+
function totalSupply() external view returns (uint);
11+
function balanceOf(address owner) external view returns (uint);
12+
function allowance(address owner, address spender) external view returns (uint);
13+
function DOMAIN_SEPARATOR() external view returns (bytes32);
14+
function PERMIT_TYPEHASH() external pure returns (bytes32);
15+
function nonces(address owner) external view returns (uint);
16+
17+
function transfer(address to, uint value) external returns (bool);
18+
function approve(address spender, uint value) external returns (bool);
19+
function transferFrom(address from, address to, uint value) external returns (bool);
20+
function permit(
21+
address owner, address spender, uint value, uint nonce, uint expiration, uint8 v, bytes32 r, bytes32 s
22+
)
23+
external;
24+
}

contracts/interfaces/IUniswapV2.sol renamed to contracts/interfaces/IUniswapV2Exchange.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
pragma solidity 0.5.15;
22

3-
interface IUniswapV2 {
3+
interface IUniswapV2Exchange {
44
event Mint(address indexed sender, uint amount0, uint amount1);
55
event Burn(address indexed sender, uint amount0, uint amount1, address indexed to);
66
event Swap(address indexed sender, address indexed tokenIn, uint amountIn, uint amountOut, address indexed to);

contracts/test/GenericERC20.sol

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
pragma solidity 0.5.15;
2+
3+
import "../UniswapV2Exchange.sol";
4+
5+
contract GenericERC20 is UniswapV2Exchange {
6+
constructor(uint _totalSupply) public {
7+
if (_totalSupply > 0) _mint(msg.sender, _totalSupply);
8+
}
9+
}

test/ERC20.spec.ts renamed to test/UniswapV2ERC20.spec.ts

Lines changed: 14 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -2,46 +2,36 @@ import path from 'path'
22
import chai from 'chai'
33
import { solidity, createMockProvider, getWallets, deployContract } from 'ethereum-waffle'
44
import { Contract } from 'ethers'
5-
import { AddressZero, MaxUint256 } from 'ethers/constants'
5+
import { MaxUint256 } from 'ethers/constants'
66
import { bigNumberify, hexlify, keccak256, defaultAbiCoder, toUtf8Bytes } from 'ethers/utils'
77
import { ecsign } from 'ethereumjs-util'
88

99
import { expandTo18Decimals, getApprovalDigest } from './shared/utilities'
1010

11-
import ERC20 from '../build/ERC20.json'
11+
import GenericERC20 from '../build/GenericERC20.json'
1212

1313
chai.use(solidity)
1414
const { expect } = chai
1515

16-
const TOKEN_DETAILS = {
17-
name: 'Test Token',
18-
symbol: 'TEST',
19-
decimals: 18,
20-
totalSupply: expandTo18Decimals(1000)
21-
}
16+
const TOTAL_SUPPLY = expandTo18Decimals(10000)
2217
const TEST_AMOUNT = expandTo18Decimals(10)
2318

24-
describe('ERC20', () => {
19+
describe('UniswapV2ERC20 via GenericERC20', () => {
2520
const provider = createMockProvider(path.join(__dirname, '..', 'waffle.json'))
2621
const [wallet, other] = getWallets(provider)
2722

2823
let token: Contract
2924
beforeEach(async () => {
30-
token = await deployContract(wallet, ERC20, [
31-
TOKEN_DETAILS.name,
32-
TOKEN_DETAILS.symbol,
33-
TOKEN_DETAILS.decimals,
34-
TOKEN_DETAILS.totalSupply
35-
])
25+
token = await deployContract(wallet, GenericERC20, [TOTAL_SUPPLY])
3626
})
3727

3828
it('name, symbol, decimals, totalSupply, balanceOf, DOMAIN_SEPARATOR, PERMIT_TYPEHASH', async () => {
3929
const name = await token.name()
40-
expect(name).to.eq(TOKEN_DETAILS.name)
41-
expect(await token.symbol()).to.eq(TOKEN_DETAILS.symbol)
42-
expect(await token.decimals()).to.eq(TOKEN_DETAILS.decimals)
43-
expect(await token.totalSupply()).to.eq(TOKEN_DETAILS.totalSupply)
44-
expect(await token.balanceOf(wallet.address)).to.eq(TOKEN_DETAILS.totalSupply)
30+
expect(name).to.eq('Uniswap V2')
31+
expect(await token.symbol()).to.eq('UNI-V2')
32+
expect(await token.decimals()).to.eq(18)
33+
expect(await token.totalSupply()).to.eq(TOTAL_SUPPLY)
34+
expect(await token.balanceOf(wallet.address)).to.eq(TOTAL_SUPPLY)
4535
expect(await token.DOMAIN_SEPARATOR()).to.eq(
4636
keccak256(
4737
defaultAbiCoder.encode(
@@ -67,18 +57,10 @@ describe('ERC20', () => {
6757
await expect(token.transfer(other.address, TEST_AMOUNT))
6858
.to.emit(token, 'Transfer')
6959
.withArgs(wallet.address, other.address, TEST_AMOUNT)
70-
expect(await token.balanceOf(wallet.address)).to.eq(TOKEN_DETAILS.totalSupply.sub(TEST_AMOUNT))
60+
expect(await token.balanceOf(wallet.address)).to.eq(TOTAL_SUPPLY.sub(TEST_AMOUNT))
7161
expect(await token.balanceOf(other.address)).to.eq(TEST_AMOUNT)
7262
})
7363

74-
it('forfeit', async () => {
75-
await expect(token.forfeit(TEST_AMOUNT))
76-
.to.emit(token, 'Transfer')
77-
.withArgs(wallet.address, AddressZero, TEST_AMOUNT)
78-
expect(await token.balanceOf(wallet.address)).to.eq(TOKEN_DETAILS.totalSupply.sub(TEST_AMOUNT))
79-
expect(await token.totalSupply()).to.eq(TOKEN_DETAILS.totalSupply.sub(TEST_AMOUNT))
80-
})
81-
8264
it('approve', async () => {
8365
await expect(token.approve(other.address, TEST_AMOUNT))
8466
.to.emit(token, 'Approval')
@@ -92,7 +74,7 @@ describe('ERC20', () => {
9274
.to.emit(token, 'Transfer')
9375
.withArgs(wallet.address, other.address, TEST_AMOUNT)
9476
expect(await token.allowance(wallet.address, other.address)).to.eq(0)
95-
expect(await token.balanceOf(wallet.address)).to.eq(TOKEN_DETAILS.totalSupply.sub(TEST_AMOUNT))
77+
expect(await token.balanceOf(wallet.address)).to.eq(TOTAL_SUPPLY.sub(TEST_AMOUNT))
9678
expect(await token.balanceOf(other.address)).to.eq(TEST_AMOUNT)
9779
})
9880

@@ -102,23 +84,12 @@ describe('ERC20', () => {
10284
.to.emit(token, 'Transfer')
10385
.withArgs(wallet.address, other.address, TEST_AMOUNT)
10486
expect(await token.allowance(wallet.address, other.address)).to.eq(MaxUint256)
105-
expect(await token.balanceOf(wallet.address)).to.eq(TOKEN_DETAILS.totalSupply.sub(TEST_AMOUNT))
87+
expect(await token.balanceOf(wallet.address)).to.eq(TOTAL_SUPPLY.sub(TEST_AMOUNT))
10688
expect(await token.balanceOf(other.address)).to.eq(TEST_AMOUNT)
10789
})
10890

109-
it('forfeitFrom', async () => {
110-
await token.approve(other.address, TEST_AMOUNT)
111-
await expect(token.connect(other).forfeitFrom(wallet.address, TEST_AMOUNT))
112-
.to.emit(token, 'Transfer')
113-
.withArgs(wallet.address, AddressZero, TEST_AMOUNT)
114-
expect(await token.allowance(wallet.address, other.address)).to.eq(0)
115-
expect(await token.balanceOf(wallet.address)).to.eq(TOKEN_DETAILS.totalSupply.sub(TEST_AMOUNT))
116-
expect(await token.totalSupply()).to.eq(TOKEN_DETAILS.totalSupply.sub(TEST_AMOUNT))
117-
expect(await token.balanceOf(other.address)).to.eq(0)
118-
})
119-
12091
it('transfer:fail', async () => {
121-
await expect(token.transfer(other.address, TOKEN_DETAILS.totalSupply.add(1))).to.be.reverted // ds-math-sub-underflow
92+
await expect(token.transfer(other.address, TOTAL_SUPPLY.add(1))).to.be.reverted // ds-math-sub-underflow
12293
await expect(token.connect(other).transfer(wallet.address, 1)).to.be.reverted // ds-math-sub-underflow
12394
})
12495

test/UniswapV2.spec.ts renamed to test/UniswapV2Exchange.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ const overrides = {
1515
gasLimit: 1000000
1616
}
1717

18-
describe('UniswapV2', () => {
18+
describe('UniswapV2Exchange', () => {
1919
const provider = createMockProvider(path.join(__dirname, '..', 'waffle.json'))
2020
const [wallet] = getWallets(provider)
2121
const loadFixture = createFixtureLoader(provider, [wallet])

test/UniswapV2Factory.spec.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { bigNumberify } from 'ethers/utils'
77
import { getCreate2Address } from './shared/utilities'
88
import { factoryFixture, FactoryFixture } from './shared/fixtures'
99

10-
import UniswapV2 from '../build/UniswapV2.json'
10+
import UniswapV2Exchange from '../build/UniswapV2Exchange.json'
1111
import { AddressZero } from 'ethers/constants'
1212

1313
chai.use(solidity)
@@ -47,7 +47,7 @@ describe('UniswapV2Factory', () => {
4747
})
4848

4949
async function createExchange(tokens: string[]) {
50-
const bytecode = `0x${UniswapV2.evm.bytecode.object}`
50+
const bytecode = `0x${UniswapV2Exchange.evm.bytecode.object}`
5151
const create2Address = getCreate2Address(factory.address, TEST_ADDRESSES.token0, TEST_ADDRESSES.token1, bytecode)
5252
await expect(factory.createExchange(...tokens))
5353
.to.emit(factory, 'ExchangeCreated')
@@ -60,7 +60,7 @@ describe('UniswapV2Factory', () => {
6060
expect(await factory.exchanges(0)).to.eq(create2Address)
6161
expect(await factory.exchangesCount()).to.eq(1)
6262

63-
const exchange = new Contract(create2Address, JSON.stringify(UniswapV2.abi), provider)
63+
const exchange = new Contract(create2Address, JSON.stringify(UniswapV2Exchange.abi), provider)
6464
expect(await exchange.factory()).to.eq(factory.address)
6565
expect(await exchange.token0()).to.eq(TEST_ADDRESSES.token0)
6666
expect(await exchange.token1()).to.eq(TEST_ADDRESSES.token1)

0 commit comments

Comments
 (0)