-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathaquaria.sol
289 lines (257 loc) · 8.2 KB
/
aquaria.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
// SPDX-License-Identifier: GPL-3.0
pragma solidity 0.8.20;
contract DexRouter {
function getAmountOut(
uint256,
uint256,
uint256
) public returns (uint256) {}
function addLiquidity(
address,
address,
uint256,
uint256,
uint256,
uint256,
address,
uint256
) public returns (bool) {}
}
contract DexFactory {
function createPair(address, address) public returns (address) {}
}
interface ERC20Token {
function transferFrom(
address _from,
address _to,
uint256 _value
) external returns (bool);
}
contract Aquaria {
event FryFish(address indexed fryer);
event FryShoaling(address indexed fryer);
event Transfer(address indexed _from, address indexed _to, uint40 _value);
event Approval(
address indexed _owner,
address indexed _spender,
uint256 _value
);
address constant zeroAddress = 0x000000000000000000000000000000000000dEaD;
DexRouter dex;
DexFactory factory;
function Existing(address _dex, address _factory) public {
dex = DexRouter(_dex);
factory = DexFactory(_factory);
}
function getAmountOut(
uint256 _amountOut,
uint256 _reserveIn,
uint256 _reserveOut
) public returns (uint256 result) {
return
dex.getAmountOut(
uint256(_amountOut),
uint256(_reserveIn),
uint256(_reserveOut)
);
}
function addLiquidity(
address _tokenA,
address _tokenB,
uint256 _amountADesired,
uint256 _amountBDesired,
uint256 _amountAMin,
uint256 _amountBMin,
address _to,
uint256 _deadline
) public returns (bool success) {
return
dex.addLiquidity(
_tokenA,
_tokenB,
_amountADesired,
_amountBDesired,
_amountAMin,
_amountBMin,
_to,
_deadline
);
}
function createPair(address _tokenA, address _tokenB)
public
returns (address LP)
{
return factory.createPair(_tokenA, _tokenB);
}
address constant dexRouter = 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D;
address constant dexFactory = 0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f;
function convertToDecimal(uint56 amount) internal view returns (uint56) {
return uint56(amount * 10**uint56(aquaria.decimals));
}
struct SubToken {
string symbol;
uint56 totalSupply;
uint56 circulatingSupply;
mapping(address => uint40) allowance;
mapping(address => uint40) balanceOf;
}
struct AquariaInfo {
string name;
uint8 decimals;
uint56 burnedFish;
SubToken fish;
SubToken shoaling;
}
AquariaInfo private aquaria;
constructor() {
aquaria.name = "Aquaria";
aquaria.decimals = 7;
aquaria.fish.symbol = "FISH";
aquaria.fish.totalSupply = convertToDecimal(1);
aquaria.fish.circulatingSupply = convertToDecimal(1);
aquaria.fish.balanceOf[msg.sender] = uint40(convertToDecimal(1));
aquaria.fish.allowance[msg.sender] = 0;
aquaria.shoaling.symbol = "SHOALING";
Existing(dexRouter, dexFactory);
}
function name() public view returns (string memory) {
return aquaria.name;
}
function symbol() public view returns (string memory) {
return aquaria.fish.symbol;
}
function decimals() public view returns (uint8) {
return aquaria.decimals;
}
function totalSupply() public view returns (uint56) {
return aquaria.fish.totalSupply;
}
function circulatingSupply() public view returns (uint56) {
return aquaria.fish.circulatingSupply;
}
function burnedFish() public view returns (uint56) {
return aquaria.burnedFish;
}
function universalBalanceOf(address _owner, string memory _token)
public
view
returns (uint40)
{
if (
keccak256(abi.encodePacked(_token)) ==
keccak256(abi.encodePacked(aquaria.fish.symbol))
) {
return aquaria.fish.balanceOf[_owner];
} else if (
keccak256(abi.encodePacked(_token)) ==
keccak256(abi.encodePacked(aquaria.shoaling.symbol))
) {
return aquaria.shoaling.balanceOf[_owner];
} else {
revert(
"Invalid fish input. We only work with fish or shoaling here, pal"
);
}
}
function balanceOf(address _owner) public view returns (uint40) {
return universalBalanceOf(_owner, aquaria.fish.symbol);
}
function allowance(address _owner) public view returns (uint40 remaining) {
return aquaria.fish.allowance[_owner];
}
function transferFrom(
address _from,
address _to,
uint16 _value
) public returns (bool success) {
require(_from == msg.sender, "You don't control these fish, my guy");
require(
_value <= aquaria.fish.allowance[_from],
"Illigal fish transaction, overrides allowance"
);
require(
_value <= aquaria.fish.balanceOf[_from],
"Go fish dude, you are out of fish"
);
require(_to != address(0), "Invalid recipient");
uint16 feeAmount = (_value * 1) / 100;
uint16 transferAmount = _value - feeAmount;
aquaria.fish.balanceOf[_from] -= _value;
aquaria.fish.balanceOf[zeroAddress] += feeAmount;
aquaria.fish.balanceOf[_to] += transferAmount;
aquaria.fish.circulatingSupply -= feeAmount;
aquaria.burnedFish += feeAmount;
emit Transfer(msg.sender, _to, _value);
return true;
}
function transfer(address _to, uint16 _value)
public
returns (bool success)
{
bool isSent = transferFrom(msg.sender, _to, _value);
return isSent;
}
function approve(address _spender, uint40 _value)
public
returns (bool success)
{
require(_spender == msg.sender, "Wrong wallet, fat finger.");
aquaria.fish.allowance[_spender] = _value;
emit Approval(msg.sender, _spender, _value);
return true;
}
function mintFish(address _minter, uint40 _value)
public
returns (bool success)
{
require(
_minter == msg.sender,
"You're trying to breed fish into someone elses wallet, don't do that"
);
require(
_value <= aquaria.fish.allowance[_minter],
"Illigal fish transaction, overrides allowance"
);
uint40 mintedAmount = _value * 2;
aquaria.fish.balanceOf[_minter] += mintedAmount;
aquaria.fish.totalSupply += mintedAmount;
aquaria.fish.circulatingSupply += mintedAmount;
return true;
}
function mergeFish(uint40 _value) public returns (bool success) {
require(
_value % convertToDecimal(100) == 0,
"Wrong fish to shoaling ratio, noob"
);
require(
_value <= aquaria.fish.allowance[msg.sender],
"Illigal fish transaction, overrides allowance"
);
aquaria.fish.balanceOf[msg.sender] -= _value;
aquaria.fish.circulatingSupply -= _value;
aquaria.burnedFish += _value;
aquaria.shoaling.balanceOf[msg.sender] += _value / 100;
aquaria.shoaling.totalSupply += _value / 100;
aquaria.shoaling.circulatingSupply += _value / 100;
return true;
}
function flushToilet(address _shitcoin, uint256 _amount)
public
returns (bool success)
{
require(
_shitcoin != address(0),
"Cant fish with non existant shitcoins, dude"
);
ERC20Token shitcoin = ERC20Token(_shitcoin);
require(
shitcoin.transferFrom(msg.sender, address(this), _amount),
"transaction failed"
);
uint40 mintableFish = uint40(
getAmountOut(_amount, uint160(_shitcoin), uint160(address(this)))
);
mintFish(msg.sender, mintableFish);
return true;
}
}