Fix bugs / Add functionality
MODIFY
dist/common/Web3Client.d.ts
dist/common/Web3Client.d.ts
@@ -14,4 +14,5 @@ export default class Web3Client {
getMaticWeb3(): Web3;
setParentDefaultOptions(options: any): void;
setMaticDefaultOptions(options: any): void;
+ setParentProvider(provider: any): void;
}

MODIFY
dist/common/Web3Client.js
dist/common/Web3Client.js
@@ -59,13 +59,15 @@ var Web3Client = /** @class */ (function () {
var _options;
return __generator(this, function (_a) {
_options = options || this.parentDefaultOptions;
+ if (!_options.from)
+ return [2 /*return*/, new Error('from is not specified')];
+ _options.gas = _options.gas || 0;
// since we use the delegated proxy patterns, the following should be a good way to provide enough gas
// apparently even when provided with a buffer of 20k, the call reverts. This shouldn't be happening because the actual gas used is less than what the estimation returns
// providing higher buffer for now
- if (!_options.from)
- return [2 /*return*/, new Error('from is not specified')];
- console.log(_options);
- // _options.gas = (await method.estimateGas()) + 200000
+ // @todo handle hex values of gas
+ _options.gas = _options.gas + 1000000;
+ console.log('sending tx on mainchain with', _options);
return [2 /*return*/, method.send(_options)];
});
});
@@ -84,8 +86,7 @@ var Web3Client = /** @class */ (function () {
_options = options || this.maticDefaultOptions;
if (!_options.from)
return [2 /*return*/, new Error('from is not specified')];
- console.log(_options);
- // _options.gas = await method.estimateGas()
+ console.log('sending tx on matic with', _options);
return [2 /*return*/, method.send(_options)];
});
});
@@ -102,6 +103,9 @@ var Web3Client = /** @class */ (function () {
Web3Client.prototype.setMaticDefaultOptions = function (options) {
this.maticDefaultOptions = options;
};
+ Web3Client.prototype.setParentProvider = function (provider) {
+ this.parentWeb3 = new web3_1.default(provider);
+ };
return Web3Client;
}());
exports.default = Web3Client;

MODIFY
dist/index.js
dist/index.js
@@ -25,7 +25,3 @@ var Matic = /** @class */ (function () {
return Matic;
}());
exports.default = Matic;
-// export default async function initialize(options) {
-// const matic = new Matic(options)
-// return matic.initialize()
-// }

MODIFY
dist/root/DepositManager.d.ts
dist/root/DepositManager.d.ts
@@ -9,7 +9,7 @@ export default class DepositManager extends ContractsBase {
depositERC20(token: address, amount: BN | string, options?: SendOptions): Promise<any>;
depositERC721(token: address, tokenId: string, options?: SendOptions): Promise<any>;
depositBulk(tokens: address[], amountOrTokenIds: string[], user: address, options?: SendOptions): Promise<any>;
- depositERC20ForUser(token: address, amount: string, user: address, options?: SendOptions): Promise<any>;
+ depositERC20ForUser(token: address, amount: BN | string, user: address, options?: SendOptions): Promise<any>;
depositERC721ForUser(token: address, tokenId: string, user: address, options?: SendOptions): Promise<any>;
depositEther(amount: string, options?: SendOptions): Promise<any>;
getAddress(): string;

MODIFY
dist/root/DepositManager.js
dist/root/DepositManager.js
@@ -35,7 +35,7 @@ var DepositManager = /** @class */ (function (_super) {
return this.web3Client.send(this.depositManagerContract.methods.depositBulk(tokens, amountOrTokenIds, user), options);
};
DepositManager.prototype.depositERC20ForUser = function (token, amount, user, options) {
- return this.web3Client.send(this.depositManagerContract.methods.depositERC20ForUser(token, user, amount), options);
+ return this.web3Client.send(this.depositManagerContract.methods.depositERC20ForUser(token, user, this.encode(amount)), options);
};
DepositManager.prototype.depositERC721ForUser = function (token, tokenId, user, options) {
return this.web3Client.send(this.depositManagerContract.methods.depositERC721ForUser(token, user, tokenId), options);

MODIFY
dist/root/Registry.js
dist/root/Registry.js
@@ -22,7 +22,6 @@ var DepositManager = /** @class */ (function (_super) {
__extends(DepositManager, _super);
function DepositManager(registry, web3Client) {
var _this = _super.call(this, web3Client) || this;
- console.log('registry', registry);
_this.registry = new _this.web3Client.parentWeb3.eth.Contract(Registry_json_1.default.abi, registry);
return _this;
}

MODIFY
dist/root/RootChain.js
dist/root/RootChain.js
@@ -77,36 +77,37 @@ var RootChain = /** @class */ (function (_super) {
return [4 /*yield*/, this.web3Client.call(this.rootChain.methods.currentHeaderBlock())];
case 1:
end = new (_a.apply(bn_js_1.default, [void 0, _b.sent()]))().div(new bn_js_1.default(10000));
- console.log(start.toString(), end.toString());
_b.label = 2;
case 2:
- if (!(start <= end)) return [3 /*break*/, 4];
- if (start == end) {
+ if (!start.lte(end)) return [3 /*break*/, 4];
+ if (start.eq(end)) {
ans = start;
return [3 /*break*/, 4];
}
mid = start.add(end).div(new bn_js_1.default(2));
- // if (!mid.mod(new BN('10000')).eq(new BN(0))) mid.sub(new BN('5000'))
- console.log('mid', mid.toString());
- return [4 /*yield*/, this.web3Client.call(this.rootChain.methods.headerBlocks(mid.mul(new bn_js_1.default(10000)).toString()))];
+ console.log({ start: start.toString(), mid: mid.toString(), end: end.toString() });
+ return [4 /*yield*/, this.web3Client.call(this.rootChain.methods.headerBlocks(mid.mul(new bn_js_1.default(10000)).toString()))
+ // console.log('headerBlock', headerBlock)
+ ];
case 3:
headerBlock = _b.sent();
headerStart = new bn_js_1.default(headerBlock.start);
headerEnd = new bn_js_1.default(headerBlock.end);
if (headerStart.lte(childBlockNumber) && childBlockNumber.lte(headerEnd)) {
+ // if childBlockNumber is between the upper and lower bounds of the headerBlock, we found our answer
ans = mid;
return [3 /*break*/, 4];
}
else if (headerStart.gt(childBlockNumber)) {
- end = mid;
+ // childBlockNumber was checkpointed before this header
+ end = mid.sub(new bn_js_1.default(1));
}
else if (headerEnd.lt(childBlockNumber)) {
- start = mid;
+ // childBlockNumber was checkpointed after this header
+ start = mid.add(new bn_js_1.default(1));
}
return [3 /*break*/, 2];
- case 4: return [2 /*return*/, ans.mul(new bn_js_1.default(10000))
- // return new BN(851).mul(new BN(10000))
- ];
+ case 4: return [2 /*return*/, ans.mul(new bn_js_1.default(10000))];
}
});
});

MODIFY
dist/root/WithdrawManager.d.ts
dist/root/WithdrawManager.d.ts
@@ -14,6 +14,7 @@ export default class WithdrawManager extends ContractsBase {
initialize(): Promise<void>;
burnERC20Tokens(token: address, amount: BN | string, options?: SendOptions): Promise<any>;
startExitWithBurntERC20Tokens(burnERC20TxHash: any, options?: any): Promise<any>;
- buildPayload(headerNumber: any, buildBlockProof: any, blockNumber: any, timestamp: any, transactionsRoot: any, receiptsRoot: any, receipt: any, receiptParentNodes: any, path: any, logIndex: any): any;
+ processExits(token: address, options?: SendOptions): Promise<any>;
+ private _buildPayloadForExit;
private _getERC20TokenContract;
}

MODIFY
dist/root/WithdrawManager.js
dist/root/WithdrawManager.js
@@ -77,7 +77,6 @@ var WithdrawManager = /** @class */ (function (_super) {
case 0: return [4 /*yield*/, this.registry.registry.methods.erc20Predicate().call()];
case 1:
erc20PredicateAddress = _a.sent();
- console.log('erc20PredicateAddress', erc20PredicateAddress);
this.erc20Predicate = new this.web3Client.parentWeb3.eth.Contract(ERC20Predicate_json_1.default.abi, erc20PredicateAddress);
return [2 /*return*/];
}
@@ -123,16 +122,24 @@ var WithdrawManager = /** @class */ (function (_super) {
return [4 /*yield*/, proofs_js_1.default.getReceiptProof(receipt, block, this.web3Client.getMaticWeb3())];
case 8:
receiptProof = _a.sent();
- payload = this.buildPayload(headerBlockNumber, blockProof, burnTx.blockNumber, block.timestamp, Buffer.from(block.transactionsRoot.slice(2), 'hex'), Buffer.from(block.receiptsRoot.slice(2), 'hex'), proofs_js_1.default.getReceiptBytes(receipt), // rlp encoded
+ payload = this._buildPayloadForExit(headerBlockNumber, blockProof, burnTx.blockNumber, block.timestamp, Buffer.from(block.transactionsRoot.slice(2), 'hex'), Buffer.from(block.receiptsRoot.slice(2), 'hex'), proofs_js_1.default.getReceiptBytes(receipt), // rlp encoded
receiptProof.parentNodes, receiptProof.path, 1 // logIndex
);
- console.log('payload', payload);
+ console.log('startExitWithBurntTokens payload', payload);
return [2 /*return*/, this.web3Client.send(this.erc20Predicate.methods.startExitWithBurntTokens(payload), options)];
}
});
});
};
- WithdrawManager.prototype.buildPayload = function (headerNumber, buildBlockProof, blockNumber, timestamp, transactionsRoot, receiptsRoot, receipt, receiptParentNodes, path, logIndex) {
+ WithdrawManager.prototype.processExits = function (token, options) {
+ options = options || {};
+ if (!options || !options.gas || options.gas < 2000000) {
+ console.log('processExits can be gas expensive, sending in 2000000 gas but even this might not be enough');
+ options.gas = 2000000;
+ }
+ return this.web3Client.send(this.withdrawManager.methods.processExits(token), options);
+ };
+ WithdrawManager.prototype._buildPayloadForExit = function (headerNumber, buildBlockProof, blockNumber, timestamp, transactionsRoot, receiptsRoot, receipt, receiptParentNodes, path, logIndex) {
return ethereumjs_util_1.default.bufferToHex(ethereumjs_util_1.default.rlp.encode([
headerNumber,
buildBlockProof,

MODIFY
src/common/Web3Client.ts
src/common/Web3Client.ts
@@ -20,12 +20,14 @@ export default class Web3Client {
async send(method, options?) {
const _options = options || this.parentDefaultOptions
+ if (!_options.from) return new Error('from is not specified')
+ _options.gas = _options.gas || 0
// since we use the delegated proxy patterns, the following should be a good way to provide enough gas
// apparently even when provided with a buffer of 20k, the call reverts. This shouldn't be happening because the actual gas used is less than what the estimation returns
// providing higher buffer for now
- if (!_options.from) return new Error('from is not specified')
- console.log(_options)
- // _options.gas = (await method.estimateGas()) + 200000
+ // @todo handle hex values of gas
+ _options.gas = _options.gas + 1000000
+ console.log('sending tx on mainchain with', _options)
return method.send(_options)
}
@@ -36,8 +38,7 @@ export default class Web3Client {
async sendOnMatic(method, options?) {
const _options = options || this.maticDefaultOptions
if (!_options.from) return new Error('from is not specified')
- console.log(_options)
- // _options.gas = await method.estimateGas()
+ console.log('sending tx on matic with', _options)
return method.send(_options)
}
@@ -56,4 +57,8 @@ export default class Web3Client {
setMaticDefaultOptions(options: any) {
this.maticDefaultOptions = options
}
+
+ setParentProvider(provider) {
+ this.parentWeb3 = new Web3(provider)
+ }
}

MODIFY
src/index.ts
src/index.ts
@@ -25,8 +25,3 @@ export default class Matic {
])
}
}
-
-// export default async function initialize(options) {
-// const matic = new Matic(options)
-// return matic.initialize()
-// }

MODIFY
src/root/DepositManager.ts
src/root/DepositManager.ts
@@ -35,9 +35,9 @@ export default class DepositManager extends ContractsBase {
)
}
- depositERC20ForUser(token: address, amount: string, user: address, options?: SendOptions) {
+ depositERC20ForUser(token: address, amount: BN | string, user: address, options?: SendOptions) {
return this.web3Client.send(
- this.depositManagerContract.methods.depositERC20ForUser(token, user, amount),
+ this.depositManagerContract.methods.depositERC20ForUser(token, user, this.encode(amount)),
options
)
}

MODIFY
src/root/Registry.ts
src/root/Registry.ts
@@ -11,7 +11,6 @@ export default class DepositManager extends ContractsBase {
constructor(registry: address, web3Client: Web3Client) {
super(web3Client)
- console.log('registry', registry)
this.registry = new this.web3Client.parentWeb3.eth.Contract(RegistryArtifact.abi, registry)
}
}

MODIFY
src/root/RootChain.ts
src/root/RootChain.ts
@@ -4,7 +4,6 @@ import RootChainArtifact from 'matic-protocol/contracts-core/artifacts/RootChain
import ContractsBase from '../common/ContractsBase'
import { address } from '../types/Common'
import Web3Client from '../common/Web3Client'
-import Proofs from 'matic-protocol/contracts-core/helpers/proofs.js'
import BN from 'bn.js'
export default class RootChain extends ContractsBase {
@@ -21,29 +20,35 @@ export default class RootChain extends ContractsBase {
async findHeaderBlockNumber(childBlockNumber: BN | string | number): Promise<BN> {
childBlockNumber = new BN(childBlockNumber)
+ // first checkpoint id = start * 10000
let start = new BN(1)
+
+ // last checkpoint id = end * 10000
let end = new BN(await this.web3Client.call(this.rootChain.methods.currentHeaderBlock())).div(new BN(10000))
- console.log(start.toString(), end.toString())
+
+ // binary search on all the checkpoints to find the checkpoint that contains the childBlockNumber
let ans
- while(start <= end) {
- if (start == end) { ans = start; break; }
+ while(start.lte(end)) {
+ if (start.eq(end)) { ans = start; break; }
let mid = start.add(end).div(new BN(2))
- // if (!mid.mod(new BN('10000')).eq(new BN(0))) mid.sub(new BN('5000'))
- console.log('mid', mid.toString())
+ console.log({ start: start.toString(), mid: mid.toString(), end: end.toString() })
const headerBlock = await this.web3Client.call(this.rootChain.methods.headerBlocks(mid.mul(new BN(10000)).toString()))
+ // console.log('headerBlock', headerBlock)
const headerStart = new BN(headerBlock.start)
const headerEnd = new BN(headerBlock.end)
if (headerStart.lte(childBlockNumber) && childBlockNumber.lte(headerEnd)) {
+ // if childBlockNumber is between the upper and lower bounds of the headerBlock, we found our answer
ans = mid
break
} else if (headerStart.gt(childBlockNumber)) {
- end = mid
+ // childBlockNumber was checkpointed before this header
+ end = mid.sub(new BN(1))
} else if (headerEnd.lt(childBlockNumber)) {
- start = mid
+ // childBlockNumber was checkpointed after this header
+ start = mid.add(new BN(1))
}
}
return ans.mul(new BN(10000))
- // return new BN(851).mul(new BN(10000))
}
getRawContract() {

MODIFY
src/root/WithdrawManager.ts
src/root/WithdrawManager.ts
@@ -28,7 +28,6 @@ export default class WithdrawManager extends ContractsBase {
async initialize() {
const erc20PredicateAddress = await this.registry.registry.methods.erc20Predicate().call()
- console.log('erc20PredicateAddress', erc20PredicateAddress)
this.erc20Predicate = new this.web3Client.parentWeb3.eth.Contract(ERC20PredicateArtifact.abi, erc20PredicateAddress)
}
@@ -64,7 +63,7 @@ export default class WithdrawManager extends ContractsBase {
)
console.log('blockProof', blockProof)
const receiptProof = await Proofs.getReceiptProof(receipt, block, this.web3Client.getMaticWeb3())
- const payload = this.buildPayload(
+ const payload = this._buildPayloadForExit(
headerBlockNumber,
blockProof,
burnTx.blockNumber,
@@ -76,14 +75,26 @@ export default class WithdrawManager extends ContractsBase {
receiptProof.path,
1 // logIndex
)
- console.log('payload', payload)
+ console.log('startExitWithBurntTokens payload', payload)
return this.web3Client.send(
this.erc20Predicate.methods.startExitWithBurntTokens(payload),
options
)
}
- buildPayload(
+ processExits(token: address, options?: SendOptions) {
+ options = options || {}
+ if (!options || !options.gas || options.gas < 2000000) {
+ console.log('processExits can be gas expensive, sending in 2000000 gas but even this might not be enough')
+ options.gas = 2000000
+ }
+ return this.web3Client.send(
+ this.withdrawManager.methods.processExits(token),
+ options
+ )
+ }
+
+ private _buildPayloadForExit(
headerNumber, buildBlockProof, blockNumber, timestamp, transactionsRoot, receiptsRoot, receipt, receiptParentNodes, path, logIndex) {
return ethUtils.bufferToHex(ethUtils.rlp.encode([
headerNumber,

Fix bugs / Add functionality