Skip to content

Commit

Permalink
feat: modify por calculation according to the new flow changes (#16)
Browse files Browse the repository at this point in the history
* feat: modify por calculation according to the new flow changes

* feat: remove funding state from vaultstate
  • Loading branch information
Polybius93 authored Jul 12, 2024
1 parent a20b638 commit 6e1e479
Show file tree
Hide file tree
Showing 7 changed files with 50 additions and 47 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"type": "module",
"name": "dlc-btc-lib",
"version": "1.0.18",
"version": "1.0.19",
"description": "This library provides a comprehensive set of interfaces and functions for minting dlcBTC tokens on supported blockchains.",
"main": "dist/index.js",
"types": "dist/index.d.ts",
Expand Down
26 changes: 12 additions & 14 deletions src/functions/proof-of-reserve/proof-of-reserve-functions.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Network } from 'bitcoinjs-lib';
import { RawVault } from 'src/models/ethereum-models.js';

import { RawVault } from '../../models/ethereum-models.js';
import { isNonEmptyString } from '../../utilities/index.js';
import {
createTaprootMultisigPayment,
deriveUnhardenedPublicKey,
Expand All @@ -18,20 +19,21 @@ export async function verifyVaultDeposit(
bitcoinBlockchainBlockHeight: number,
bitcoinBlockchainAPI: string,
bitcoinNetwork: Network
): Promise<boolean> {
): Promise<number> {
try {
const fundingTransaction = await fetchBitcoinTransaction(
vault.fundingTxId,
bitcoinBlockchainAPI
);
if (!isNonEmptyString(vault.wdTxId) && !isNonEmptyString(vault.fundingTxId)) return 0;

const txID = isNonEmptyString(vault.wdTxId) ? vault.wdTxId : vault.fundingTxId;

const fundingTransaction = await fetchBitcoinTransaction(txID, bitcoinBlockchainAPI);

const isFundingTransactionConfirmed = await checkBitcoinTransactionConfirmations(
fundingTransaction,
bitcoinBlockchainBlockHeight
);

if (!isFundingTransactionConfirmed) {
return false;
return 0;
}

const unspendableKeyCommittedToUUID = deriveUnhardenedPublicKey(
Expand All @@ -52,16 +54,12 @@ export async function verifyVaultDeposit(
);

if (!vaultTransactionOutput) {
return false;
}

if (vaultTransactionOutput.value !== vault.valueLocked.toNumber()) {
return false;
return 0;
}

return true;
return vaultTransactionOutput.value;
} catch (error) {
console.log(`Error verifying Vault Deposit: ${error}`);
return false;
return 0;
}
}
1 change: 0 additions & 1 deletion src/models/ethereum-models.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ export enum VaultState {
CLOSING = 2,
CLOSED = 3,
PENDING = 4,
FUNDING = 5,
}

export interface RawVault {
Expand Down
10 changes: 4 additions & 6 deletions src/proof-of-reserve-handlers/proof-of-reserve-handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,17 +31,15 @@ export class ProofOfReserveHandler {
);

const verifiedDeposits = await Promise.all(
vaults.map(async vault => {
return (await verifyVaultDeposit(
vaults.map(vault =>
verifyVaultDeposit(
vault,
derivedAttestorGroupPublicKey,
bitcoinBlockchainBlockHeight,
this.bitcoinBlockchainAPI,
this.bitcoinNetwork
)) === true
? vault.valueLocked.toNumber()
: 0;
})
)
)
);
return verifiedDeposits.reduce((a, b) => a + b, 0);
}
Expand Down
4 changes: 4 additions & 0 deletions src/utilities/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ export function isDefined<T>(argument: T | undefined): argument is T {
return !isUndefined(argument);
}

export function isNonEmptyString(string: string | undefined): boolean {
return isDefined(string) && string !== '';
}

export function compareUint8Arrays(a: Uint8Array, b: Uint8Array): boolean {
return a.length === b.length && a.every((value, index) => value === b[index]);
}
Expand Down
33 changes: 8 additions & 25 deletions tests/unit/proof-of-reserve.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import { TEST_TESTNET_ATTESTOR_UNHARDENED_DERIVED_PUBLIC_KEY_1 } from '../mocks/
import {
TEST_TESTNET_FUNDING_TRANSACTION_1,
TEST_TESTNET_FUNDING_TRANSACTION_2,
TEST_TESTNET_FUNDING_TRANSACTION_3,
} from '../mocks/bitcoin-transaction.test.constants.js';
import {
TEST_BITCOIN_BLOCKCHAIN_BLOCK_HEIGHT_1,
Expand All @@ -20,7 +19,7 @@ describe('Proof of Reserve Calculation', () => {
jest.clearAllMocks();
});
describe('verifyVaultDeposit', () => {
it("should return true when the vault's funding transaction is confirmed, contains an output with the multisig's script, and the output's value matches the vault's valueLocked field", async () => {
it("should return the expected value when the vault's funding transaction is confirmed, contains an output with the multisig's script, and the output's value matches the vault's valueLocked field", async () => {
jest
.spyOn(bitcoinRequestFunctions, 'fetchBitcoinTransaction')
.mockImplementationOnce(async () => TEST_TESTNET_FUNDING_TRANSACTION_1);
Expand All @@ -33,10 +32,10 @@ describe('Proof of Reserve Calculation', () => {
testnet
);

expect(result).toBe(true);
expect(result).toBe(10000000);
});

it('should return false if the funding transaction is not found', async () => {
it('should return 0 if the funding transaction is not found', async () => {
jest
.spyOn(bitcoinRequestFunctions, 'fetchBitcoinTransaction')
.mockImplementationOnce(async () => {
Expand All @@ -51,10 +50,10 @@ describe('Proof of Reserve Calculation', () => {
testnet
);

expect(result).toBe(false);
expect(result).toBe(0);
});

it("should return false when the vault's funding transaction is not yet confirmed", async () => {
it("should return 0 when the vault's funding transaction is not yet confirmed", async () => {
jest
.spyOn(bitcoinRequestFunctions, 'fetchBitcoinTransaction')
.mockImplementationOnce(async () => TEST_TESTNET_FUNDING_TRANSACTION_1);
Expand All @@ -67,10 +66,10 @@ describe('Proof of Reserve Calculation', () => {
testnet
);

expect(result).toBe(false);
expect(result).toBe(0);
});

it("should return false if the vault's funding transaction lacks an output with the multisig's script", async () => {
it("should return 0 if the vault's funding transaction lacks an output with the multisig's script", async () => {
jest
.spyOn(bitcoinRequestFunctions, 'fetchBitcoinTransaction')
.mockImplementationOnce(async () => TEST_TESTNET_FUNDING_TRANSACTION_2);
Expand All @@ -83,23 +82,7 @@ describe('Proof of Reserve Calculation', () => {
testnet
);

expect(result).toBe(false);
});

it("should return false if the output value related to the multisig script differs from the vault's valueLocked field in the funding transaction", async () => {
jest
.spyOn(bitcoinRequestFunctions, 'fetchBitcoinTransaction')
.mockImplementationOnce(async () => TEST_TESTNET_FUNDING_TRANSACTION_3);

const result = await verifyVaultDeposit(
TEST_VAULT_2,
Buffer.from(TEST_TESTNET_ATTESTOR_UNHARDENED_DERIVED_PUBLIC_KEY_1, 'hex'),
TEST_BITCOIN_BLOCKCHAIN_BLOCK_HEIGHT_1,
TEST_TESTNET_BITCOIN_BLOCKCHAIN_API,
testnet
);

expect(result).toBe(false);
expect(result).toBe(0);
});
});
});
21 changes: 21 additions & 0 deletions tests/unit/utility.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
customShiftValue,
delay,
isDefined,
isNonEmptyString,
isUndefined,
reverseBytes,
shiftValue,
Expand Down Expand Up @@ -88,6 +89,26 @@ describe('Utility Functions', () => {
});
});

describe('isNonEmptyString', () => {
it('correctly identifies if a string is defined and not empty', () => {
const value = 'Hello, World!';
const isValueDefinedAndNotEmpty = isNonEmptyString(value);
expect(isValueDefinedAndNotEmpty).toBe(true);
});

it('correctly identifies if a string is not defined', () => {
const value = undefined;
const isValueDefinedAndNotEmpty = isNonEmptyString(value);
expect(isValueDefinedAndNotEmpty).toBe(false);
});

it('correctly identifies if a string is defined but empty', () => {
const value = '';
const isValueDefinedAndNotEmpty = isNonEmptyString(value);
expect(isValueDefinedAndNotEmpty).toBe(false);
});
});

describe('compareUint8Arrays', () => {
it('correctly compares two Uint8Arrays for equality', () => {
const uint8ArrayA = new Uint8Array([
Expand Down

0 comments on commit 6e1e479

Please sign in to comment.