Skip to content

Commit

Permalink
test: add script to register pegin and tests for mainnet real cases
Browse files Browse the repository at this point in the history
  • Loading branch information
Luisfc68 committed Sep 27, 2024
1 parent bd99e5a commit c73612f
Show file tree
Hide file tree
Showing 4 changed files with 217 additions and 2 deletions.
3 changes: 2 additions & 1 deletion example.env
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
ALPHANET_RPC_URL=http://127.0.0.1:4444
MAINNET_RPC_URL=https://public-node.rsk.co
TESTNET_RPC_URL=https://public-node.testnet.rsk.co
TESTNET_RPC_URL=https://public-node.testnet.rsk.co
MAINNET_SIGNER_PRIVATE_KEY=<private_key>
119 changes: 119 additions & 0 deletions scripts/registerPegin.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
require('dotenv').config();
const bs58check = require('bs58check');
const Web3 = require("web3");
const web3Provider = new Web3.providers.HttpProvider(process.env.MAINNET_RPC_URL);
const web3 = new Web3(web3Provider);

const LBC_ADDRESS = "0xAA9cAf1e3967600578727F975F283446A3Da6612";

// ------ REPLACE THE FOLLOWING DATA WITH THE DATA OF THE PEGIN YOU WANT TO REGISTER ------

const quoteJson = {
"fedBTCAddr": "3LxPz39femVBL278mTiBvgzBNMVFqXssoH",
"lbcAddr": "0xAA9cAf1e3967600578727F975F283446A3Da6612",
"lpRSKAddr": "0x4202bac9919c3412fc7c8be4e678e26279386603",
"btcRefundAddr": "171gGjg8NeLUonNSrFmgwkgT1jgqzXR6QX",
"rskRefundAddr": "0xaD0DE1962ab903E06C725A1b343b7E8950a0Ff82",
"lpBTCAddr": "17kksixYkbHeLy9okV16kr4eAxVhFkRhP",
"callFee": "100000000000000",
"penaltyFee": "10000000000000",
"contractAddr": "0xaD0DE1962ab903E06C725A1b343b7E8950a0Ff82",
"data": "",
"gasLimit": 21000,
"nonce": "8373381263192041574",
"value": "8000000000000000",
"agreementTimestamp": "1727298699",
"timeForDeposit": 3600,
"lpCallTime": 7200,
"confirmations": 2,
"callOnRegister": false,
"gasFee": "1341211956000",
"productFeeAmount": 0
};

const expectedHash = "9ef0d0c376a0611ee83a1d938f88cdc8694d9cb6e35780d253fb945e92647d68";

const signature = "8ccd018b5c1fb7eceba2a13f8c977ae362c0daccafa6d77a5eb740527dd177620bb6c2d072d68869b3a08b193b1356de564e73233ea1c2686078bf87e3c909a31c";

const btcRawTx = "010000000148e9e71dafee5a901be4eceb5aca361c083481b70496f4e3da71e5d969add1820000000017160014b88ef07cd7bcc022b6d73c4764ce5db0887d5b05ffffffff02965c0c000000000017a9141b67149e474f0d7757181f4db89257f27a64738387125b01000000000017a914785c3e807e54dc41251d6377da0673123fa87bc88700000000";

const pmt = "a71100000e7fe369f81a807a962c8e528debd0b46cbfa4f8dfbc02a62674dd41a73f4c4bde0508a9e309e5836703375a58ab116b95434552ca2e460c3273cd2caa13350aefc3c8152a8150f738cd18ff33e69f19b727bff9c2b92aa06e6d0971e9b49893075f2d926bbb9f0884640363b79b6a668a178f140c13f25b48ec975357822ce38c733f6de9b32f6910ff3cd838efd274cd784ab204b74f281ef68146c334f509613d022554f281465dfcd597305c988c4b06e297e5d777afdb66c3391c3c471ebf9a1e051ba38201f08ca758d2dc83a71c34088e6785c1a775e2bde492361462cac9e7042653341cd1e190d0265a33f46ba564dc6116689cf19a8af6816c006df69803008246d44bc849babfbcc3de601fba3d10d696bf4b4d9cb8e291584e7d24bb2c81282972e71cb4493fb4966fcb483d6b62b24a0e25f912ee857d8843e4fa6181b8351f0a300e14503d51f46f367ec872712004535a56f14c65430f044f9685137a1afb2dc0aa402fde8d83b072ef0c4357529466e017dfb2935444103bbeec61bf8944924371921eefd02f35fd5283f3b7bce58a6f4ca15fb32cee8869be8d7720501ec18cc097c236b19212514582212719aede2400b1dd1ff43208ac7504bfb60a00";

const height = 862859;

// ------ END OF THE DATA TO BE REPLACED ------

module.exports = async function (callback) {
try {
web3.eth.accounts.wallet.add("0x"+process.env.MAINNET_SIGNER_PRIVATE_KEY);
const signer = web3.eth.accounts.wallet[0];
const registerPeginCaller = signer.address;
console.log('Executing registerPegIn from ' + registerPeginCaller);

const json = require("../build/contracts/LiquidityBridgeContractV2.json");
const contract = new web3.eth.Contract(json.abi, LBC_ADDRESS);
const quote = {
fedBtcAddress: bs58check.decode(quoteJson.fedBTCAddr).slice(1),
lbcAddress: quoteJson.lbcAddr,
liquidityProviderRskAddress: quoteJson.lpRSKAddr,
btcRefundAddress: bs58check.decode(quoteJson.btcRefundAddr),
rskRefundAddress: quoteJson.rskRefundAddr,
liquidityProviderBtcAddress: bs58check.decode(quoteJson.lpBTCAddr),
callFee: quoteJson.callFee,
penaltyFee: quoteJson.penaltyFee,
contractAddress: quoteJson.contractAddr,
data: '0x',
gasLimit: quoteJson.gasLimit,
nonce: quoteJson.nonce,
value: quoteJson.value,
agreementTimestamp: quoteJson.agreementTimestamp,
timeForDeposit: quoteJson.timeForDeposit,
callTime: quoteJson.lpCallTime,
depositConfirmations: quoteJson.confirmations,
callOnRegister: quoteJson.callOnRegister,
productFeeAmount: quoteJson.productFeeAmount,
gasFee: quoteJson.gasFee
};
const quoteHash = await contract.methods.hashQuote(Object.values(quote))
.call({ to: LBC_ADDRESS })
.then(result => result.slice(2));
if (quoteHash !== expectedHash) {
throw new Error(`Invalid hash: ${quoteHash}`);
}
console.log("Quote hash is correct", quoteHash);

const gasEstimation = await contract.methods.registerPegIn(
Object.values(quote),
'0x' + signature,
'0x' + btcRawTx,
'0x' + pmt,
height
).estimateGas();

console.log("Gas estimation: ", gasEstimation);

const registerPeginResult = await contract.methods.registerPegIn(
Object.values(quote),
'0x' + signature,
'0x' + btcRawTx,
'0x' + pmt,
height
).call({ to: LBC_ADDRESS, from: registerPeginCaller, gasLimit: gasEstimation });

console.log("Expected result: ", registerPeginResult);
const receipt = await contract.methods.registerPegIn(
Object.values(quote),
'0x' + signature,
'0x' + btcRawTx,
'0x' + pmt,
height
).send({ to: LBC_ADDRESS, from: registerPeginCaller, gasLimit: gasEstimation + 200 });
console.log("Receipt: ");
console.log(receipt);

} catch (error) {
console.error("Error running register pegin script: ");
console.error(error);
}
callback();
};
95 changes: 95 additions & 0 deletions test/basic.tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,101 @@ contract("LiquidityBridgeContractV2.sol", async (accounts) => {
);
});

it('should refund pegin with wrong amount without penalizing the LP (real cases)', async () => {
const cases = [
{
quote: {
fedBtcAddress: bs58check.decode("3LxPz39femVBL278mTiBvgzBNMVFqXssoH").slice(1),
lbcAddress: '0xAA9cAf1e3967600578727F975F283446A3Da6612',
liquidityProviderRskAddress: '0x4202bac9919c3412fc7c8be4e678e26279386603',
btcRefundAddress: bs58check.decode("1K5X7aTGfZGksihgNdDschakaxp8ZhT1F3"),
rskRefundAddress: '0x1bf357F3CcCe62a5Dd1035c79070BdA219C53B10',
liquidityProviderBtcAddress: bs58check.decode("17kksixYkbHeLy9okV16kr4eAxVhFkRhP"),
callFee: web3.utils.toBN('100000000000000'),
penaltyFee: web3.utils.toBN('10000000000000'),
contractAddress: '0x1bf357F3CcCe62a5Dd1035c79070BdA219C53B10',
data:'0x',
gasLimit: 21000,
nonce: '907664817259568253',
value: web3.utils.toBN('5200000000000000'),
agreementTimestamp: 1727278204,
timeForDeposit: 3600,
callTime: 7200,
depositConfirmations: 2,
callOnRegister: false,
productFeeAmount: 0,
gasFee: web3.utils.toBN('1354759560000'),
},
quoteHash: 'b21ead431a1c3efd1759b62a56c253d740d1bf3c3673cd060aed64906a82c1c3',
signature: 'c72e3e5bb9cf6bf3db568df18d2dba80896490cda7371c4643cad116d54d46c50a368d4cfa0b963468c5db15b773f4d1ea1ab69565a3f903ac3ab363204ba3bc1c',
btcRawTx: '020000000212bebc8ba671aa9af2e3984af89366b5594ed115dbbaef64a41e8650cd4a53ea0000000017160014fe7b123124c87300e8ba30f0e2eafdd8e1f2b337ffffffff046d8f4e5fa8d6cc5fa23c50640249461b646e8a4722c9cfbfbff00c049d559f0000000017160014fe7b123124c87300e8ba30f0e2eafdd8e1f2b337ffffffff02d71608000000000017a9149fa51efd2954990e4974e7b13468fb8be54512d8872d2507000000000017a914b979999438ade0fdd2cf303fca55ea29aec2392b8700000000',
pmt: '800c00000d3eb13be27a4110f06ca8e4b4b00103e10ac6ba5f9123934764ac9555e2ec3c7b88a5464adca8b40a548741a8262dc2ab228f89cbd51bbf57f3f5d67130820ae3f9b7625821c2d9718d6611de40edfa1eb42181f180aab3891730584921a125dddba628c1d3f5fca59e0b68494aae191ab14db30b79e07962da298a52bcf077905661f80bd5731e0c80524ba2f7dcad0bd05a0d470bccdb5c5889c9c71ac7c5bca7f6cebd492154af69f2b98bcf7995444c765a18445a5ef212eb5f8ead5a441a45536e4075022614df043d03b2449113a00f32cff333024d3a1d66d84d4a31c012bebc8ba671aa9af2e3984af89366b5594ed115dbbaef64a41e8650cd4a53ea34b89cb98fac941bdd048d4a8f371d7b9f132ad19f1542556c89b4e8701022de51f6d49aa8f7e7d01591de9bdef65351e8590f111ea9be5550f66a3d4a734758e26b8edf2bfe9c4375929fea7b7197a24589648f8e7b934a6caa2d9c7583e64a28db12de953b0abddbdc3edb28b845eaca02f56dd52aa04e3131dc539c0f646f35751d1ec529231acd5cb079b4a2b678ecd3fc07636be878e6336d546518562e04af6a1500',
height: 862825,
refundAmount: '5301350000000000'
},
{
quote: {
fedBtcAddress: bs58check.decode("3LxPz39femVBL278mTiBvgzBNMVFqXssoH").slice(1),
lbcAddress: '0xAA9cAf1e3967600578727F975F283446A3Da6612',
liquidityProviderRskAddress: '0x4202bac9919c3412fc7c8be4e678e26279386603',
btcRefundAddress: bs58check.decode("171gGjg8NeLUonNSrFmgwkgT1jgqzXR6QX"),
rskRefundAddress: '0xaD0DE1962ab903E06C725A1b343b7E8950a0Ff82',
liquidityProviderBtcAddress: bs58check.decode("17kksixYkbHeLy9okV16kr4eAxVhFkRhP"),
callFee: web3.utils.toBN('100000000000000'),
penaltyFee: web3.utils.toBN('10000000000000'),
contractAddress: '0xaD0DE1962ab903E06C725A1b343b7E8950a0Ff82',
data:'0x',
gasLimit: 21000,
nonce: '8373381263192041574',
value: web3.utils.toBN('8000000000000000'),
agreementTimestamp: 1727298699,
timeForDeposit: 3600,
callTime: 7200,
depositConfirmations: 2,
callOnRegister: false,
productFeeAmount: 0,
gasFee: web3.utils.toBN('1341211956000'),
},
quoteHash: '9ef0d0c376a0611ee83a1d938f88cdc8694d9cb6e35780d253fb945e92647d68',
signature: '8ccd018b5c1fb7eceba2a13f8c977ae362c0daccafa6d77a5eb740527dd177620bb6c2d072d68869b3a08b193b1356de564e73233ea1c2686078bf87e3c909a31c',
btcRawTx: '010000000148e9e71dafee5a901be4eceb5aca361c083481b70496f4e3da71e5d969add1820000000017160014b88ef07cd7bcc022b6d73c4764ce5db0887d5b05ffffffff02965c0c000000000017a9141b67149e474f0d7757181f4db89257f27a64738387125b01000000000017a914785c3e807e54dc41251d6377da0673123fa87bc88700000000',
pmt: 'a71100000e7fe369f81a807a962c8e528debd0b46cbfa4f8dfbc02a62674dd41a73f4c4bde0508a9e309e5836703375a58ab116b95434552ca2e460c3273cd2caa13350aefc3c8152a8150f738cd18ff33e69f19b727bff9c2b92aa06e6d0971e9b49893075f2d926bbb9f0884640363b79b6a668a178f140c13f25b48ec975357822ce38c733f6de9b32f6910ff3cd838efd274cd784ab204b74f281ef68146c334f509613d022554f281465dfcd597305c988c4b06e297e5d777afdb66c3391c3c471ebf9a1e051ba38201f08ca758d2dc83a71c34088e6785c1a775e2bde492361462cac9e7042653341cd1e190d0265a33f46ba564dc6116689cf19a8af6816c006df69803008246d44bc849babfbcc3de601fba3d10d696bf4b4d9cb8e291584e7d24bb2c81282972e71cb4493fb4966fcb483d6b62b24a0e25f912ee857d8843e4fa6181b8351f0a300e14503d51f46f367ec872712004535a56f14c65430f044f9685137a1afb2dc0aa402fde8d83b072ef0c4357529466e017dfb2935444103bbeec61bf8944924371921eefd02f35fd5283f3b7bce58a6f4ca15fb32cee8869be8d7720501ec18cc097c236b19212514582212719aede2400b1dd1ff43208ac7504bfb60a00',
height: 862859,
refundAmount: '8101340000000000'
}
]
for (const testCase of cases) {

/**
* We perform this modifications because even that these are test cases that happened with actual mainnet
* transactions, the amounts are too small to be used in regtest, so we need to adapt them to the test environment
* also, the LBC address is different, so we modify that value as well
*/
const modifiedQuote = structuredClone(testCase.quote);
const regtestMultiplier = web3.utils.toBN('100');
modifiedQuote.lbcAddress = instance.address;
modifiedQuote.value = testCase.quote.value.mul(regtestMultiplier);
modifiedQuote.gasFee = testCase.quote.gasFee.mul(regtestMultiplier);
modifiedQuote.callFee = testCase.quote.callFee.mul(regtestMultiplier);
const modifiedRefundAmount = web3.utils.toBN(testCase.refundAmount).mul(regtestMultiplier);

const quoteHash = await instance.hashQuote(utils.asArray(modifiedQuote));
await bridgeMockInstance.setPegin(quoteHash, { value: modifiedRefundAmount });
const receipt = await instance.registerPegIn(utils.asArray(modifiedQuote), '0x'+testCase.signature, '0x'+testCase.btcRawTx, '0x'+testCase.pmt, testCase.height);
expect(receipt.logs.length).to.be.eq(2);
truffleAssertions.eventEmitted(receipt, "Refund", {
dest: testCase.quote.rskRefundAddress,
amount: modifiedRefundAmount,
success: true,
quoteHash: quoteHash
});
truffleAssertions.eventEmitted(receipt, "PegInRegistered", {
quoteHash: quoteHash,
transferredAmount: modifiedRefundAmount
});
}
});

it("should register liquidity provider", async () => {
let currAddr = accounts[9];
let existing = await instance.getCollateral(currAddr);
Expand Down
2 changes: 1 addition & 1 deletion truffle-config.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ module.exports = {
},
rskMainnet: {
provider: () => new HDWalletProvider({
mnemonic,
privateKeys: [process.env.MAINNET_SIGNER_PRIVATE_KEY],
providerOrUrl: process.env.MAINNET_RPC_URL,
derivationPath: "m/44'/137'/0'/0/",
pollingInterval: 30000,
Expand Down

0 comments on commit c73612f

Please sign in to comment.