Skip to content

Commit 661fc37

Browse files
committed
add script to deploy enhanced step functions contract.
1 parent b688b26 commit 661fc37

File tree

2 files changed

+329
-1
lines changed

2 files changed

+329
-1
lines changed

web3deployment/compileContracts.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ const solc = require('solc');
44
const contractPath = path.join(__dirname, "../contracts/");
55
const input = {
66
"ConversionRates.sol" : fs.readFileSync(contractPath + 'reserves/fprConversionRate/ConversionRates.sol','utf8'),
7-
"VolumeImbalanceRecorder.sol" : fs.readFileSync(contractPath + 'reserves/VolumeImbalanceRecorder.sol', 'utf8'),
7+
"EnhancedStepFunctions.sol" : fs.readFileSync(contractPath + 'reserves/fprConversionRate/EnhancedStepFunctions.sol', 'utf8'),
88
"ConversionRatesInterface.sol" : fs.readFileSync(contractPath + 'ConversionRatesInterface.sol', 'utf8'),
99
"PermissionGroups.sol" : fs.readFileSync(contractPath + 'PermissionGroups.sol', 'utf8'),
1010
"ERC20Interface.sol" : fs.readFileSync(contractPath + 'ERC20Interface.sol', 'utf8'),

web3deployment/reserveDeployer2.js

Lines changed: 328 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,328 @@
1+
#!/usr/bin/env node
2+
3+
const Web3 = require("web3");
4+
const fs = require("fs");
5+
const path = require('path');
6+
const RLP = require('rlp');
7+
const BigNumber = require('bignumber.js')
8+
9+
process.on('unhandledRejection', console.error.bind(console))
10+
11+
const { configPath, gasPriceGwei, printPrivateKey, rpcUrl, signedTxOutput, dontSendTx, networkAddress, chainId: chainIdInput } = require('yargs')
12+
.usage('Usage: $0 --config-path [path] --gas-price-gwei [gwei] --print-private-key [bool] --rpc-url [url] --signed-tx-output [path] --dont-send-tx [bool] --network-address [address] --chain-id')
13+
.demandOption(['gasPriceGwei', 'rpcUrl'])
14+
.boolean('printPrivateKey')
15+
.boolean('dontSendTx')
16+
.argv;
17+
const web3 = new Web3(new Web3.providers.HttpProvider(rpcUrl));
18+
const solc = require('solc')
19+
20+
const rand = web3.utils.randomHex(7);
21+
const privateKey = web3.utils.sha3("js sucks" + rand);
22+
//console.log("privateKey", privateKey);
23+
24+
if (printPrivateKey) {
25+
console.log("privateKey", privateKey);
26+
let path = "privatekey_" + web3.utils.randomHex(7) + ".txt";
27+
fs.writeFileSync(path, privateKey, function(err) {
28+
if(err) {
29+
return console.log(err);
30+
}
31+
});
32+
}
33+
const account = web3.eth.accounts.privateKeyToAccount(privateKey);
34+
const sender = account.address;
35+
const gasPrice = BigNumber(gasPriceGwei).mul(10 ** 9);
36+
const signedTxs = [];
37+
let nonce;
38+
let chainId = chainIdInput;
39+
40+
console.log("from",sender);
41+
42+
async function sendTx(txObject) {
43+
const txTo = txObject._parent.options.address;
44+
45+
let gasLimit;
46+
try {
47+
gasLimit = await txObject.estimateGas();
48+
}
49+
catch (e) {
50+
gasLimit = 500 * 1000;
51+
}
52+
53+
if(txTo !== null) {
54+
gasLimit = 500 * 1000;
55+
}
56+
57+
gasLimit *= 1.2;
58+
gasLimit -= gasLimit % 1;
59+
//console.log(gasLimit);
60+
const txData = txObject.encodeABI();
61+
const txFrom = account.address;
62+
const txKey = account.privateKey;
63+
64+
const tx = {
65+
from : txFrom,
66+
to : txTo,
67+
nonce : nonce,
68+
data : txData,
69+
gas : gasLimit,
70+
chainId,
71+
gasPrice
72+
};
73+
74+
const signedTx = await web3.eth.accounts.signTransaction(tx, txKey);
75+
nonce++;
76+
// don't wait for confirmation
77+
signedTxs.push(signedTx.rawTransaction)
78+
if (!dontSendTx) {
79+
web3.eth.sendSignedTransaction(signedTx.rawTransaction, {from:sender});
80+
}
81+
}
82+
83+
async function deployContract(solcOutput, contractName, ctorArgs) {
84+
85+
const actualName = contractName;
86+
const bytecode = solcOutput.contracts[actualName].bytecode;
87+
88+
const abi = solcOutput.contracts[actualName].interface;
89+
const myContract = new web3.eth.Contract(JSON.parse(abi));
90+
const deploy = myContract.deploy({data:"0x" + bytecode, arguments: ctorArgs});
91+
let address = "0x" + web3.utils.sha3(RLP.encode([sender,nonce])).slice(12).substring(14);
92+
address = web3.utils.toChecksumAddress(address);
93+
94+
await sendTx(deploy);
95+
96+
myContract.options.address = address;
97+
98+
99+
return [address,myContract];
100+
}
101+
102+
const contractPath = path.join(__dirname, "../contracts/");
103+
104+
let reserveAddress;
105+
let conversionRatesAddress;
106+
107+
let reserveContract;
108+
let conversionRatesContract;
109+
110+
let reservePermissions;
111+
let conversionRatesPermissions;
112+
113+
const depositAddresses = [];
114+
let validDurationBlock = 24;
115+
let taxWalletAddress = 0x0;
116+
let taxFeesBps = 1000;
117+
118+
const ethAddress = "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee";
119+
120+
const tokens = [];
121+
const tokenControlInfo = {};
122+
const tokenNameToAddress = { "ETH" : ethAddress };
123+
124+
125+
function parseInput( jsonInput ) {
126+
// tokens
127+
const tokenInfo = jsonInput["tokens"];
128+
Object.keys(tokenInfo).forEach(function(key) {
129+
const val = tokenInfo[key];
130+
const symbol = key;
131+
const name = val["name"];
132+
const address = val["address"];
133+
134+
tokenNameToAddress[symbol] = address;
135+
136+
tokens.push(address);
137+
const dict = {
138+
minimalRecordResolution : val["minimalRecordResolution"],
139+
maxPerBlockImbalance : val["maxPerBlockImbalance"],
140+
maxTotalImbalance : val["maxTotalImbalance"]
141+
};
142+
tokenControlInfo[address] = dict;
143+
});
144+
145+
// exchanges
146+
const exchangeInfo = jsonInput["exchanges"];
147+
Object.keys(exchangeInfo).forEach(function(exchange) {
148+
Object.keys(exchangeInfo[exchange]).forEach(function(token){
149+
const depositAddress = exchangeInfo[exchange][token];
150+
const dict = {};
151+
dict[token] = depositAddress;
152+
depositAddresses.push(dict);
153+
});
154+
});
155+
156+
reservePermissions = jsonInput.permission["KyberReserve"];
157+
conversionRatesPermissions = jsonInput.permission["ConversionRates"];
158+
validDurationBlock = jsonInput["valid duration block"];
159+
160+
// output file name
161+
outputFileName = jsonInput["output filename"];
162+
};
163+
164+
async function setPermissions(contract, alerters, operators, admin) {
165+
console.log("set operator(s) " + contract.address);
166+
for(let i = 0 ; i < operators.length ; i++ ) {
167+
const operator = operators[i];
168+
console.log(operator);
169+
await sendTx(contract.methods.addOperator(operator));
170+
}
171+
console.log("set alerter(s)");
172+
for(let i = 0 ; i < alerters.length ; i++ ) {
173+
const alerter = alerters[i];
174+
console.log(alerter);
175+
await sendTx(contract.methods.addAlerter(alerter));
176+
}
177+
178+
console.log("transferAdminQuickly");
179+
console.log(admin);
180+
await sendTx(contract.methods.transferAdminQuickly(admin));
181+
}
182+
183+
184+
async function main() {
185+
nonce = await web3.eth.getTransactionCount(sender);
186+
console.log("nonce",nonce);
187+
188+
chainId = chainId || await web3.eth.net.getId()
189+
console.log('chainId', chainId);
190+
console.log('starting compilation');
191+
output = await require("./compileContracts.js").compileContracts();
192+
console.log("finished compilation");
193+
194+
if (!dontSendTx) {
195+
await waitForEth();
196+
}
197+
198+
let networkAddress = '0x65bF64Ff5f51272f729BDcD7AcFB00677ced86Cd';
199+
console.log('network address: ', networkAddress);
200+
201+
console.log("deploying EnhancedStepFunctions");
202+
[conversionRatesAddress,conversionRatesContract] = await deployContract(output, "EnhancedStepFunctions.sol:EnhancedStepFunctions", [sender]);
203+
console.log("enhanced steps fpr pricing contract", conversionRatesAddress);
204+
205+
console.log("deploying kyber reserve");
206+
[reserveAddress,reserveContract] = await deployContract(output, "KyberReserve.sol:KyberReserve", [networkAddress,conversionRatesAddress,sender]);
207+
208+
console.log("reserve", reserveAddress);
209+
210+
console.log("deploying enhanced step functions wrapper");
211+
[wrapperAddress, wrapperContract] = await deployContract(output, "WrapConversionRate.sol:WrapConversionRate", [conversionRatesAddress]);
212+
213+
console.log("wrapperAddress", wrapperAddress);
214+
215+
operators = ['0xF76d38Da26c0c0a4ce8344370D7Ae4c34B031dea','0xf3d872b9e8d314820dc8e99dafbe1a3feedc27d5']
216+
admin = '0xf3d872b9e8d314820dc8e99dafbe1a3feedc27d5';
217+
218+
await setPermissions(reserveContract, operators, operators, admin);
219+
await setPermissions(conversionRatesContract, operators, operators, admin);
220+
await setPermissions(wrapperContract, operators, operators, admin);
221+
222+
console.log("done for now...")
223+
return;
224+
225+
// conversion rates
226+
console.log("conversion rate - add token");
227+
for( let i = 0 ; i < tokens.length ; i++ ) {
228+
console.log(tokens[i]);
229+
await sendTx(conversionRatesContract.methods.addToken(tokens[i]));
230+
}
231+
232+
console.log("conversion rate - set valid duration block");
233+
await sendTx(conversionRatesContract.methods.setValidRateDurationInBlocks(validDurationBlock));
234+
console.log("conversion rate - setReserveAddress");
235+
await sendTx(conversionRatesContract.methods.setReserveAddress(reserveAddress));
236+
237+
console.log("conversion rate - set control info");
238+
for( let i = 0 ; i < tokens.length ; i++ ) {
239+
console.log(tokens[i]);
240+
const dict = tokenControlInfo[tokens[i]];
241+
await sendTx(conversionRatesContract.methods.setTokenControlInfo(tokens[i],
242+
dict.minimalRecordResolution,
243+
dict.maxPerBlockImbalance,
244+
dict.maxTotalImbalance));
245+
}
246+
247+
console.log("conversion rate - enable token trade");
248+
for( let i = 0 ; i < tokens.length ; i++ ) {
249+
console.log(tokens[i]);
250+
const dict = tokenControlInfo[tokens[i]];
251+
await sendTx(conversionRatesContract.methods.enableTokenTrade(tokens[i]));
252+
}
253+
254+
console.log("conversion rate - add temp operator");
255+
await sendTx(conversionRatesContract.methods.addOperator(sender));
256+
console.log("conversion rate - set qty step function to 0");
257+
for( let i = 0 ; i < tokens.length ; i++ ) {
258+
console.log(tokens[i]);
259+
await sendTx(conversionRatesContract.methods.setQtyStepFunction(tokens[i],
260+
[0],
261+
[0],
262+
[0],
263+
[0]));
264+
}
265+
266+
console.log("conversion rate - set imbalance step function to 0");
267+
for( let i = 0 ; i < tokens.length ; i++ ) {
268+
console.log(tokens[i]);
269+
await sendTx(conversionRatesContract.methods.setImbalanceStepFunction(tokens[i],
270+
[0],
271+
[0],
272+
[0],
273+
[0]));
274+
}
275+
276+
console.log("conversion rate - remove temp operator");
277+
await sendTx(conversionRatesContract.methods.removeOperator(sender));
278+
279+
await setPermissions(conversionRatesContract, conversionRatesPermissions);
280+
281+
console.log("last nonce is", nonce);
282+
283+
if (signedTxOutput) {
284+
fs.writeFileSync(signedTxOutput, signedTxsJson);
285+
}
286+
}
287+
288+
function printParams(jsonInput) {
289+
dictOutput = {};
290+
dictOutput["tokens"] = jsonInput.tokens;
291+
dictOutput["tokens"]["ETH"] = {"name" : "Ethereum", "decimals" : 18, "address" : ethAddress };
292+
dictOutput["exchanges"] = jsonInput.exchanges;
293+
dictOutput["permission"] = jsonInput.permission;
294+
dictOutput["valid duration block"] = jsonInput["valid duration block"];
295+
dictOutput["reserve"] = reserveAddress;
296+
dictOutput["pricing"] = conversionRatesAddress;
297+
dictOutput["network"] = networkAddress;
298+
const json = JSON.stringify(dictOutput, null, 2);
299+
console.log(json);
300+
const outputFileName = jsonInput["output filename"];
301+
console.log(outputFileName, 'write');
302+
fs.writeFileSync(outputFileName, json);
303+
}
304+
305+
306+
function sleep(ms){
307+
return new Promise(resolve=>{
308+
setTimeout(resolve,ms)
309+
})
310+
}
311+
312+
async function waitForEth() {
313+
while(true) {
314+
const balance = await web3.eth.getBalance(sender);
315+
console.log("waiting for balance to account " + sender);
316+
if(balance.toString() !== "0") {
317+
console.log("received " + balance.toString() + " wei");
318+
return;
319+
}
320+
else await sleep(10000)
321+
}
322+
}
323+
324+
325+
let filename;
326+
let content;
327+
328+
main();

0 commit comments

Comments
 (0)