uniswap 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CHANGELOG.md +3 -0
- data/Manifest.txt +15 -0
- data/README.md +60 -0
- data/Rakefile +29 -0
- data/lib/uniswap/ERC20.rb +79 -0
- data/lib/uniswap/PublicMintERC20.rb +39 -0
- data/lib/uniswap/UniswapSetupZapV2.rb +156 -0
- data/lib/uniswap/UniswapV2Callee.rb +11 -0
- data/lib/uniswap/UniswapV2ERC20.rb +12 -0
- data/lib/uniswap/UniswapV2Factory.rb +81 -0
- data/lib/uniswap/UniswapV2Pair.rb +274 -0
- data/lib/uniswap/UniswapV2Router.rb +323 -0
- data/lib/uniswap/UniswapV2RouterWithRewards.rb +335 -0
- data/lib/uniswap/UnsafeNoApprovalERC20.rb +39 -0
- data/lib/uniswap.rb +11 -0
- metadata +112 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 06b64f10df9f1cb893dbf1e22e0c7fbbbc1a3b077c5f362d2c385ec46e321f16
|
4
|
+
data.tar.gz: edb9d0db8f5edd36a5ac62ff456483f6dad7e480ee7a911377bf48c9d83c12da
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 7264444379e503aa697de99c6fbd16d39fbcce95411d91a7a4ca053dd761886dc2fcddf9c2efa9fe4678b585dc248b4f0d54dd8eb8910d2fa4b62a46bc257560
|
7
|
+
data.tar.gz: 6b0f03feb962ad4881c5393239ab7b41f55715e7afe2160e2fcb7c38719b58d6aae903d1c821de8bb2cb3c2135bf4a474ff2c883f7aad4e1f3d3e9ca3602a7e3
|
data/CHANGELOG.md
ADDED
data/Manifest.txt
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
CHANGELOG.md
|
2
|
+
Manifest.txt
|
3
|
+
README.md
|
4
|
+
Rakefile
|
5
|
+
lib/uniswap.rb
|
6
|
+
lib/uniswap/ERC20.rb
|
7
|
+
lib/uniswap/PublicMintERC20.rb
|
8
|
+
lib/uniswap/UniswapSetupZapV2.rb
|
9
|
+
lib/uniswap/UniswapV2Callee.rb
|
10
|
+
lib/uniswap/UniswapV2ERC20.rb
|
11
|
+
lib/uniswap/UniswapV2Factory.rb
|
12
|
+
lib/uniswap/UniswapV2Pair.rb
|
13
|
+
lib/uniswap/UniswapV2Router.rb
|
14
|
+
lib/uniswap/UniswapV2RouterWithRewards.rb
|
15
|
+
lib/uniswap/UnsafeNoApprovalERC20.rb
|
data/README.md
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
# Uniswap V2 - Core (Dumb) Contracts (Rubidity Edition)
|
2
|
+
|
3
|
+
|
4
|
+
uniswap - core uniswap v2 (dumb) contracts for ruby (rubidity) for layer 1 (l1) with "off-chain" indexer
|
5
|
+
|
6
|
+
|
7
|
+
|
8
|
+
* home :: [github.com/s6ruby/rubidity](https://github.com/s6ruby/rubidity)
|
9
|
+
* bugs :: [github.com/s6ruby/rubidity/issues](https://github.com/s6ruby/rubidity/issues)
|
10
|
+
* gem :: [rubygems.org/gems/uniswap](https://rubygems.org/gems/uniswap)
|
11
|
+
* rdoc :: [rubydoc.info/gems/uniswap](http://rubydoc.info/gems/uniswap)
|
12
|
+
|
13
|
+
|
14
|
+
## What's Solidity?! What's Rubidity?!
|
15
|
+
|
16
|
+
See [**Solidity - Contract Application Binary Interface (ABI) Specification** »](https://docs.soliditylang.org/en/latest/abi-spec.html)
|
17
|
+
|
18
|
+
See [**Rubidity - Ruby for Layer 1 (L1) Contracts / Protocols with "Off-Chain" Indexer** »](https://github.com/s6ruby/rubidity)
|
19
|
+
|
20
|
+
|
21
|
+
|
22
|
+
## What's Uniswap?! What's Facetswap?!
|
23
|
+
|
24
|
+
See the [**Uniswap V2 White Paper (PDF), March 2020**](https://uniswap.org/whitepaper.pdf) or
|
25
|
+
the [**Uniswap V2 Core Contracts (in Solidity)**](https://github.com/Uniswap/v2-core).
|
26
|
+
|
27
|
+
See the [**Facetswap App / Service**](https://facetswap.com)
|
28
|
+
(running Uniswap V2 contracts in Rubidity).
|
29
|
+
|
30
|
+
|
31
|
+
|
32
|
+
|
33
|
+
## Usage
|
34
|
+
|
35
|
+
Available contracts include:
|
36
|
+
|
37
|
+
- [ERC20](lib/uniswap/ERC20.rb)
|
38
|
+
- [UniswapV2ERC20 (is ERC20)](lib/uniswap/UniswapV2ERC20.rb)
|
39
|
+
- [UniswapV2Pair (is UniswapV2ERC20)](lib/uniswap/UniswapV2Pair.rb)
|
40
|
+
- ...
|
41
|
+
|
42
|
+
And so on. To be continued ...
|
43
|
+
|
44
|
+
|
45
|
+
|
46
|
+
|
47
|
+
|
48
|
+
## Bonus - More Blockchain (Crypto) Tools, Libraries & Scripts In Ruby
|
49
|
+
|
50
|
+
See [**/blockchain**](https://github.com/rubycocos/blockchain)
|
51
|
+
at the ruby code commons (rubycocos) org.
|
52
|
+
|
53
|
+
|
54
|
+
## Questions? Comments?
|
55
|
+
|
56
|
+
Join us in the [Rubidity (community) discord (chat server)](https://discord.gg/3JRnDUap6y). Yes you can.
|
57
|
+
Your questions and commentary welcome.
|
58
|
+
|
59
|
+
Or post them over at the [Help & Support](https://github.com/geraldb/help) page. Thanks.
|
60
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'hoe'
|
2
|
+
# require './lib/uniswap/version.rb'
|
3
|
+
|
4
|
+
|
5
|
+
Hoe.spec 'uniswap' do
|
6
|
+
self.version = '0.0.1' # Rubidity::Module::Uniswap::VERSION
|
7
|
+
|
8
|
+
self.summary = 'uniswap - core uniswap v2 (dumb) contracts for ruby (rubidity) for layer 1 (l1) with "off-chain" indexer'
|
9
|
+
self.description = summary
|
10
|
+
|
11
|
+
self.urls = { home: 'https://github.com/s6ruby/rubidity' }
|
12
|
+
|
13
|
+
self.author = 'Gerald Bauer'
|
14
|
+
self.email = 'gerald.bauer@gmail.com'
|
15
|
+
|
16
|
+
# switch extension to .markdown for gihub formatting
|
17
|
+
self.readme_file = 'README.md'
|
18
|
+
self.history_file = 'CHANGELOG.md'
|
19
|
+
|
20
|
+
self.extra_deps = [
|
21
|
+
['rubidity', '>= 0.8.1'],
|
22
|
+
]
|
23
|
+
|
24
|
+
self.licenses = ['Public Domain']
|
25
|
+
|
26
|
+
self.spec_extras = {
|
27
|
+
required_ruby_version: '>= 2.3'
|
28
|
+
}
|
29
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
class ERC20 < Contract # abstract: true
|
4
|
+
|
5
|
+
event :Transfer, from: Address,
|
6
|
+
to: Address,
|
7
|
+
amount: UInt
|
8
|
+
event :Approval, owner: Address,
|
9
|
+
spender: Address,
|
10
|
+
amount: UInt
|
11
|
+
|
12
|
+
storage name: String,
|
13
|
+
symbol: String,
|
14
|
+
decimals: UInt,
|
15
|
+
totalSupply: UInt,
|
16
|
+
balanceOf: mapping( Address, UInt),
|
17
|
+
allowance: mapping( Address, mapping( Address, UInt))
|
18
|
+
|
19
|
+
sig [String, String, UInt]
|
20
|
+
def constructor(name:, symbol:, decimals:)
|
21
|
+
@name = name
|
22
|
+
@symbol = symbol
|
23
|
+
@decimals = decimals
|
24
|
+
end
|
25
|
+
|
26
|
+
sig [Address, UInt], returns: Bool
|
27
|
+
def approve( spender:, amount: )
|
28
|
+
@allowance[msg.sender][spender] = amount
|
29
|
+
|
30
|
+
log Approval, owner: msg.sender, spender: spender, amount: amount
|
31
|
+
|
32
|
+
true
|
33
|
+
end
|
34
|
+
|
35
|
+
sig [Address, UInt], returns: Bool
|
36
|
+
def transfer( to:, amount: )
|
37
|
+
assert @balanceOf[msg.sender] >= amount, "Insufficient balance"
|
38
|
+
|
39
|
+
@balanceOf[msg.sender] -= amount
|
40
|
+
@balanceOf[to] += amount
|
41
|
+
|
42
|
+
log Transfer, from: msg.sender, to: to, amount: amount
|
43
|
+
|
44
|
+
true
|
45
|
+
end
|
46
|
+
|
47
|
+
sig [Address, Address, UInt], returns: Bool
|
48
|
+
def transferFrom( from:, to:, amount: )
|
49
|
+
allowed = @allowance[from][msg.sender]
|
50
|
+
|
51
|
+
assert @balanceOf[from] >= amount, "Insufficient balance"
|
52
|
+
assert allowed >= amount, "Insufficient allowance"
|
53
|
+
|
54
|
+
@allowance[from][msg.sender] = allowed - amount
|
55
|
+
|
56
|
+
@balanceOf[from] -= amount
|
57
|
+
@balanceOf[to] += amount
|
58
|
+
|
59
|
+
log Transfer, from: from, to: to, amount: amount
|
60
|
+
|
61
|
+
true
|
62
|
+
end
|
63
|
+
|
64
|
+
sig [Address, UInt]
|
65
|
+
def _mint( to:, amount: )
|
66
|
+
@totalSupply += amount
|
67
|
+
@balanceOf[to] += amount
|
68
|
+
|
69
|
+
log Transfer, from: address(0), to: to, amount: amount
|
70
|
+
end
|
71
|
+
|
72
|
+
sig [Address, UInt]
|
73
|
+
def _burn( from:, amount: )
|
74
|
+
@balanceOf[from] -= amount
|
75
|
+
@totalSupply -= amount
|
76
|
+
|
77
|
+
log Transfer, from: from, to: address(0), amount: amount
|
78
|
+
end
|
79
|
+
end # class ERC20
|
@@ -0,0 +1,39 @@
|
|
1
|
+
pragma :rubidity, "1.0.0"
|
2
|
+
|
3
|
+
import 'ERC20'
|
4
|
+
|
5
|
+
contract :PublicMintERC20, is: :ERC20 do
|
6
|
+
uint256 :public, :maxSupply
|
7
|
+
uint256 :public, :perMintLimit
|
8
|
+
|
9
|
+
constructor(
|
10
|
+
name: :string,
|
11
|
+
symbol: :string,
|
12
|
+
maxSupply: :uint256,
|
13
|
+
perMintLimit: :uint256,
|
14
|
+
decimals: :uint8
|
15
|
+
) do
|
16
|
+
super(name: name, symbol: symbol, decimals: decimals)
|
17
|
+
s.maxSupply = maxSupply
|
18
|
+
s.perMintLimit = perMintLimit
|
19
|
+
end
|
20
|
+
|
21
|
+
|
22
|
+
function :mint, { amount: :uint256 }, :public do
|
23
|
+
require(amount > 0, 'Amount must be positive')
|
24
|
+
require(amount <= s.perMintLimit, 'Exceeded mint limit')
|
25
|
+
|
26
|
+
require(s.totalSupply + amount <= s.maxSupply, 'Exceeded max supply')
|
27
|
+
|
28
|
+
_mint(to: msg.sender, amount: amount)
|
29
|
+
end
|
30
|
+
|
31
|
+
function :airdrop, { to: :address, amount: :uint256 }, :public do
|
32
|
+
require(amount > 0, 'Amount must be positive')
|
33
|
+
require(amount <= s.perMintLimit, 'Exceeded mint limit')
|
34
|
+
|
35
|
+
require(s.totalSupply + amount <= s.maxSupply, 'Exceeded max supply')
|
36
|
+
|
37
|
+
_mint(to: to, amount: amount)
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,156 @@
|
|
1
|
+
pragma :rubidity, "1.0.0"
|
2
|
+
|
3
|
+
import 'UniswapV2Factory'
|
4
|
+
import 'UnsafeNoApprovalERC20'
|
5
|
+
import 'UniswapV2Router'
|
6
|
+
import 'PublicMintERC20'
|
7
|
+
|
8
|
+
contract :UniswapSetupZapV2 do
|
9
|
+
array :address, :public, :factories
|
10
|
+
array :address, :public, :tokenAs
|
11
|
+
array :address, :public, :tokenBs
|
12
|
+
array :address, :public, :pairs
|
13
|
+
array :address, :public, :routers
|
14
|
+
|
15
|
+
string :public, :name
|
16
|
+
|
17
|
+
event :ZapOneSetup, { factory: :address, tokenA: :address, tokenB: :address, pair: :address, router: :address }
|
18
|
+
|
19
|
+
constructor() {
|
20
|
+
s.name = 'UniswapSetupZapV2'
|
21
|
+
}
|
22
|
+
|
23
|
+
function :zapDumbSwap, { etherAddress: :address, admin: :address }, :public do
|
24
|
+
ether = ERC20(etherAddress)
|
25
|
+
etherBalance = ether.balanceOf(address(this))
|
26
|
+
|
27
|
+
require(etherBalance > 10.ether, 'Not enough ether')
|
28
|
+
|
29
|
+
factory = new UniswapV2Factory(_feeToSetter: address(this))
|
30
|
+
factory.setFeeTo(admin)
|
31
|
+
factory.setFeeToSetter(admin)
|
32
|
+
|
33
|
+
router = new UniswapV2Router(
|
34
|
+
_factory: factory,
|
35
|
+
_WETH: address(0)
|
36
|
+
)
|
37
|
+
|
38
|
+
ether.approve(router, (2 ** 255))
|
39
|
+
|
40
|
+
names = array(:string)
|
41
|
+
symbols = array(:string)
|
42
|
+
|
43
|
+
names.push("Chameleon")
|
44
|
+
symbols.push("CHAM")
|
45
|
+
|
46
|
+
names.push("Mirage")
|
47
|
+
symbols.push("MIR")
|
48
|
+
|
49
|
+
names.push("Emerald")
|
50
|
+
symbols.push("EMD")
|
51
|
+
|
52
|
+
names.push("Oasis")
|
53
|
+
symbols.push("OAS")
|
54
|
+
|
55
|
+
names.push("Paradox")
|
56
|
+
symbols.push("PARA")
|
57
|
+
|
58
|
+
names.push("Peridot")
|
59
|
+
symbols.push("PERI")
|
60
|
+
|
61
|
+
for i in 0...names.length
|
62
|
+
supply = ((i + 1) * 2000).ether
|
63
|
+
|
64
|
+
token = new PublicMintERC20(
|
65
|
+
name: names[i],
|
66
|
+
symbol: symbols[i],
|
67
|
+
maxSupply: supply,
|
68
|
+
perMintLimit: supply,
|
69
|
+
decimals: 18
|
70
|
+
)
|
71
|
+
|
72
|
+
token.mint(amount: supply)
|
73
|
+
token.approve(router, (2 ** 255))
|
74
|
+
|
75
|
+
router.addLiquidity(
|
76
|
+
tokenA: etherAddress,
|
77
|
+
tokenB: token,
|
78
|
+
amountADesired: etherBalance.div(names.length),
|
79
|
+
amountBDesired: supply,
|
80
|
+
amountAMin: 0,
|
81
|
+
amountBMin: 0,
|
82
|
+
to: admin,
|
83
|
+
deadline: block.timestamp + 1000
|
84
|
+
)
|
85
|
+
end
|
86
|
+
|
87
|
+
return nil
|
88
|
+
end
|
89
|
+
|
90
|
+
function :doZapOld, :public do
|
91
|
+
factory = new UniswapV2Factory(_feeToSetter: msg.sender)
|
92
|
+
|
93
|
+
tokenA = new UnsafeNoApprovalERC20(
|
94
|
+
name: "TokenA (#{block.number})",
|
95
|
+
symbol: "TKA",
|
96
|
+
)
|
97
|
+
|
98
|
+
tokenB = new UnsafeNoApprovalERC20(
|
99
|
+
name: "TokenB (#{block.number})",
|
100
|
+
symbol: "TKB",
|
101
|
+
)
|
102
|
+
|
103
|
+
router = new UniswapV2Router(
|
104
|
+
_factory: factory,
|
105
|
+
_WETH: address(this)
|
106
|
+
)
|
107
|
+
|
108
|
+
pair = factory.createPair(tokenA, tokenB)
|
109
|
+
|
110
|
+
tokenA.airdrop(to: msg.sender, amount: 1e6.ether)
|
111
|
+
tokenB.airdrop(to: msg.sender, amount: 1e6.ether)
|
112
|
+
|
113
|
+
s.factories.push(factory)
|
114
|
+
s.tokenAs.push(tokenA)
|
115
|
+
s.tokenBs.push(tokenB)
|
116
|
+
s.pairs.push(pair)
|
117
|
+
s.routers.push(router)
|
118
|
+
|
119
|
+
emit :ZapOneSetup, { factory: factory, tokenA: tokenA, tokenB: tokenB, pair: pair, router: router }
|
120
|
+
end
|
121
|
+
|
122
|
+
function :lastZap, :public, :view, returns: { factory: :address, tokenA: :address, tokenB: :address, pair: :address, router: :address } do
|
123
|
+
return {
|
124
|
+
factory: s.factories[s.factories.length - 1],
|
125
|
+
tokenA: s.tokenAs[s.tokenAs.length - 1],
|
126
|
+
tokenB: s.tokenBs[s.tokenBs.length - 1],
|
127
|
+
pair: s.pairs[s.pairs.length - 1],
|
128
|
+
router: s.routers[s.routers.length - 1]
|
129
|
+
}
|
130
|
+
end
|
131
|
+
|
132
|
+
function :userStats, {
|
133
|
+
user: :address,
|
134
|
+
router: :address,
|
135
|
+
factory: :address,
|
136
|
+
tokenA: :address,
|
137
|
+
tokenB: :address,
|
138
|
+
}, :public, :view, returns: {
|
139
|
+
userTokenABalance: :uint256,
|
140
|
+
userTokenBBalance: :uint256,
|
141
|
+
tokenAReserves: :uint256,
|
142
|
+
tokenBReserves: :uint256,
|
143
|
+
userLPBalance: :uint256
|
144
|
+
} do
|
145
|
+
tokenAReserves, tokenBReserves = UniswapV2Router(router).getReserves(factory, tokenA, tokenB)
|
146
|
+
pair = UniswapV2Factory(factory).getPair(tokenA, tokenB)
|
147
|
+
|
148
|
+
return {
|
149
|
+
userTokenABalance: ERC20(tokenA).balanceOf(user),
|
150
|
+
userTokenBBalance: ERC20(tokenB).balanceOf(user),
|
151
|
+
tokenAReserves: tokenAReserves,
|
152
|
+
tokenBReserves: tokenBReserves,
|
153
|
+
userLPBalance: UniswapV2ERC20(pair).balanceOf(user)
|
154
|
+
}
|
155
|
+
end
|
156
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
pragma :rubidity, "1.0.0"
|
2
|
+
|
3
|
+
import 'UniswapV2Pair'
|
4
|
+
|
5
|
+
|
6
|
+
contract :UniswapV2Factory do
|
7
|
+
address :public, :feeTo
|
8
|
+
address :public, :feeToSetter
|
9
|
+
|
10
|
+
mapping ({ address: mapping({ address: :address })}), :public, :getPair
|
11
|
+
array :address, :public, :allPairs
|
12
|
+
|
13
|
+
event :PairCreated, { token0: :address, token1: :address, pair: :address, pairLength: :uint256 }
|
14
|
+
|
15
|
+
constructor(_feeToSetter: :address) do
|
16
|
+
s.feeToSetter = _feeToSetter
|
17
|
+
end
|
18
|
+
|
19
|
+
function :allPairsLength, {}, :public, :view, returns: :uint256 do
|
20
|
+
return s.allPairs.length
|
21
|
+
end
|
22
|
+
|
23
|
+
function :getAllPairs, {}, :public, :view, returns: [:address] do
|
24
|
+
return s.allPairs
|
25
|
+
end
|
26
|
+
|
27
|
+
function :createPair, { tokenA: :address, tokenB: :address }, :public, returns: :address do
|
28
|
+
require(tokenA != tokenB, 'Scribeswap: IDENTICAL_ADDRESSES')
|
29
|
+
|
30
|
+
token0, token1 = uint256( tokenA ) < uint256( tokenB ) ? [tokenA, tokenB] : [tokenB, tokenA]
|
31
|
+
|
32
|
+
require(token0 != address(0), "Scribeswap: ZERO_ADDRESS");
|
33
|
+
require(s.getPair[token0][token1] == address(0), "Scribeswap: PAIR_EXISTS");
|
34
|
+
|
35
|
+
=begin
|
36
|
+
salt = keccak256(abi.encodePacked(token0, token1))
|
37
|
+
|
38
|
+
pair = new UniswapV2Pair({ salt: salt })
|
39
|
+
pair.init(token0, token1)
|
40
|
+
|
41
|
+
s.getPair[token0][token1] = pair
|
42
|
+
s.getPair[token1][token0] = pair
|
43
|
+
|
44
|
+
s.allPairs.push(pair)
|
45
|
+
emit(:PairCreated, { token0: token0, token1: token1, pair: pair, pairLength: s.allPairs.length })
|
46
|
+
|
47
|
+
return pair
|
48
|
+
=end
|
49
|
+
|
50
|
+
## fix-fix-fix - auto set call stack/msg.sender
|
51
|
+
Runtime.msg.sender = __address__
|
52
|
+
pair = UniswapV2Pair.construct
|
53
|
+
pair.init( token0, token1 )
|
54
|
+
|
55
|
+
s.getPair[token0][token1] = pair.__address__
|
56
|
+
s.getPair[token1][token0] = pair.__address__
|
57
|
+
|
58
|
+
s.allPairs.push( pair.__address__ )
|
59
|
+
emit :PairCreated, token0: token0, token1: token1, pair: pair.__address__, pairLength: s.allPairs.length
|
60
|
+
|
61
|
+
return pair.__address__
|
62
|
+
end
|
63
|
+
|
64
|
+
|
65
|
+
|
66
|
+
function :setFeeTo, { _feeTo: :address }, :public do
|
67
|
+
require(msg.sender == feeToSetter, "Scribeswap: FORBIDDEN")
|
68
|
+
|
69
|
+
s.feeTo = _feeTo
|
70
|
+
|
71
|
+
return nil
|
72
|
+
end
|
73
|
+
|
74
|
+
function :setFeeToSetter, { _feeToSetter: :address }, :public do
|
75
|
+
require(msg.sender == feeToSetter, "Scribeswap: FORBIDDEN")
|
76
|
+
|
77
|
+
s.feeToSetter = _feeToSetter
|
78
|
+
|
79
|
+
return nil
|
80
|
+
end
|
81
|
+
end
|