Skip to content

Commit

Permalink
Added additional system test scenario
Browse files Browse the repository at this point in the history
  • Loading branch information
tomaszslabon committed Jul 13, 2023
1 parent f987652 commit 8380f5b
Showing 1 changed file with 275 additions and 1 deletion.
276 changes: 275 additions & 1 deletion system-tests/test/deposit-redemption.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ describe("System Test - Deposit and redemption", () => {
let systemTestsContext: SystemTestsContext
let electrumClient: ElectrumClient
let bridgeAddress: string
let vaultAddress: string
let maintainerBridgeHandle: EthereumBridge
let depositorBridgeHandle: EthereumBridge
let bank: Contract
Expand Down Expand Up @@ -77,6 +78,7 @@ describe("System Test - Deposit and redemption", () => {
)

bridgeAddress = deployedContracts.Bridge.address
vaultAddress = deployedContracts.TBTCVault.address

maintainerBridgeHandle = new EthereumBridge({
address: bridgeAddress,
Expand All @@ -103,7 +105,7 @@ describe("System Test - Deposit and redemption", () => {
)
})

context("when deposit is made and revealed", () => {
context("when deposit is made and revealed without a vault", () => {
before("make and reveal deposit", async () => {
deposit = generateDeposit(
systemTestsContext.depositor.address,
Expand Down Expand Up @@ -372,4 +374,276 @@ describe("System Test - Deposit and redemption", () => {
})
})
})

context("when deposit is made and revealed with a vault", () => {
before("make and reveal deposit", async () => {
deposit = generateDeposit(
systemTestsContext.depositor.address,
depositAmount,
systemTestsContext.walletBitcoinKeyPair.publicKey.compressed,
vaultAddress,
)

console.log(`
Generated deposit data:
${JSON.stringify(deposit)}
`)
;({ depositUtxo } = await submitDepositTransaction(
deposit,
systemTestsContext.depositorBitcoinKeyPair.wif,
electrumClient,
true
))

console.log(`
Deposit made on BTC chain:
- Transaction hash: ${depositUtxo.transactionHash}
- Output index: ${depositUtxo.outputIndex}
`)

// Since the reveal deposit logic does not perform SPV proof, we
// can reveal the deposit transaction immediately without waiting
// for confirmations.
await TBTC.revealDeposit(
depositUtxo,
deposit,
electrumClient,
depositorBridgeHandle,
deposit.vault,
)

console.log(`
Deposit revealed on Ethereum chain
`)
})

it("should broadcast the deposit transaction on the Bitcoin network", async () => {
expect(
(await electrumClient.getRawTransaction(depositUtxo.transactionHash))
.transactionHex.length
).to.be.greaterThan(0)
})

it("should reveal the deposit to the bridge", async () => {
const { revealedAt } = await TBTC.getRevealedDeposit(
depositUtxo,
maintainerBridgeHandle
)
expect(revealedAt).to.be.greaterThan(0)
})

context("when deposit is swept and sweep proof submitted", () => {
before("sweep the deposit and submit sweep proof", async () => {
;({ newMainUtxo: sweepUtxo } = await submitDepositSweepTransaction(
electrumClient,
depositSweepTxFee,
systemTestsContext.walletBitcoinKeyPair.wif,
true,
[depositUtxo],
[deposit]
))

console.log(`
Deposit swept on Bitcoin chain:
- Transaction hash: ${sweepUtxo.transactionHash}
`)

// Unlike in the deposit transaction case, we must wait for the sweep
// transaction to have an enough number of confirmations. This is
// because the bridge performs the SPV proof of that transaction.
await waitTransactionConfirmed(
electrumClient,
sweepUtxo.transactionHash
)

await fakeRelayDifficulty(
relay,
electrumClient,
sweepUtxo.transactionHash
)

// TODO: Consider fetching the current wallet main UTXO and passing it
// here. This will allow running this test scenario multiple
// times for the same wallet.
await SpvMaintainer.submitDepositSweepProof(
sweepUtxo.transactionHash,
// This is the first sweep of the given wallet so there is no main UTXO.
{
// The function expects an unprefixed hash.
transactionHash: BitcoinTransactionHash.from(constants.HashZero),
outputIndex: 0,
value: BigNumber.from(0),
},
maintainerBridgeHandle,
electrumClient
)

console.log(`
Deposit sweep proved on the bridge
`)
})

it("should broadcast the sweep transaction on the Bitcoin network", async () => {
expect(
(await electrumClient.getRawTransaction(sweepUtxo.transactionHash))
.transactionHex.length
).to.be.greaterThan(0)
})

it("should sweep the deposit on the bridge", async () => {
const { sweptAt } = await TBTC.getRevealedDeposit(
depositUtxo,
maintainerBridgeHandle
)
expect(sweptAt).to.be.greaterThan(0)
})

it("should increase depositor's balance in the bank", async () => {
const { treasuryFee } = await TBTC.getRevealedDeposit(
depositUtxo,
maintainerBridgeHandle
)

const expectedBalance = depositAmount
.sub(treasuryFee)
.sub(depositSweepTxFee)

const actualBalance = await bank.balanceOf(
systemTestsContext.depositor.address
)

expect(actualBalance).to.be.equal(expectedBalance)
})

context("when redemption is requested", () => {
let requestedAmount: BigNumber
let redeemerOutputScript: string
let redemptionRequest: RedemptionRequest

before("request the redemption", async () => {
// Redeem the full depositor's balance.
requestedAmount = await bank.balanceOf(
systemTestsContext.depositor.address
)

// Allow the bridge to take the redeemed bank balance.
await bank
.connect(systemTestsContext.depositor)
.approveBalance(bridgeAddress, requestedAmount)

// Request redemption to depositor's address.
redeemerOutputScript = `0014${computeHash160(
systemTestsContext.depositorBitcoinKeyPair.publicKey.compressed
)}`

await depositorBridgeHandle.requestRedemption(
systemTestsContext.walletBitcoinKeyPair.publicKey.compressed,
sweepUtxo,
redeemerOutputScript,
requestedAmount,
)

console.log(
`Requested redemption of amount ${requestedAmount} to script ${redeemerOutputScript} on the bridge`
)

redemptionRequest = await TBTC.getRedemptionRequest(
systemTestsContext.walletBitcoinKeyPair.publicKey.compressed,
redeemerOutputScript,
"pending",
maintainerBridgeHandle
)
})

it("should transfer depositor's bank balance to the Bridge", async () => {
expect(
await bank.balanceOf(systemTestsContext.depositor.address)
).to.be.equal(0)

expect(await bank.balanceOf(bridgeAddress)).to.be.equal(
requestedAmount
)
})

it("should register the redemption request on the bridge", async () => {
expect(redemptionRequest.requestedAt).to.be.greaterThan(0)
expect(redemptionRequest.requestedAmount).to.be.equal(requestedAmount)
expect(redemptionRequest.redeemerOutputScript).to.be.equal(
redeemerOutputScript
)
})

context(
"when redemption is made and redemption proof submitted",
() => {
let redemptionTxHash: BitcoinTransactionHash

before(
"make the redemption and submit redemption proof",
async () => {
;({ transactionHash: redemptionTxHash } =
await submitRedemptionTransaction(
electrumClient,
maintainerBridgeHandle,
systemTestsContext.walletBitcoinKeyPair.wif,
sweepUtxo,
[redemptionRequest.redeemerOutputScript],
true
))

console.log(
"Redemption made on Bitcoin chain:\n" +
`- Transaction hash: ${redemptionTxHash}`
)

await waitTransactionConfirmed(electrumClient, redemptionTxHash)

await fakeRelayDifficulty(
relay,
electrumClient,
redemptionTxHash
)

await SpvMaintainer.submitRedemptionProof(
redemptionTxHash,
sweepUtxo,
systemTestsContext.walletBitcoinKeyPair.publicKey.compressed,
maintainerBridgeHandle,
electrumClient
)

console.log("Redemption proved on the bridge")
}
)

it("should broadcast the redemption transaction on the Bitcoin network", async () => {
expect(
(await electrumClient.getRawTransaction(redemptionTxHash))
.transactionHex.length
).to.be.greaterThan(0)
})

it("should close the redemption request on the bridge", async () => {
await expect(
TBTC.getRedemptionRequest(
systemTestsContext.walletBitcoinKeyPair.publicKey.compressed,
redemptionRequest.redeemerOutputScript,
"pending",
maintainerBridgeHandle
)
).to.be.rejectedWith(
"Provided redeemer output script and wallet public key do not identify a redemption request"
)
})

it("should decrease Bridge's balance in the bank", async () => {
const actualBalance = await bank.balanceOf(bridgeAddress)

expect(actualBalance).to.be.equal(0)
})
}
)
})
})
})
})

0 comments on commit 8380f5b

Please sign in to comment.