Skip to content

Commit

Permalink
Include unallocated balance in releaseDeposit function
Browse files Browse the repository at this point in the history
We were not including the unallocated balance in the releaseDeposit function.
If there was no Mezo deposit, but some funds were donated to the contract
they would be stuck there forever. This change allows the contract to release
both unallocated balance and Mezo deposit.
  • Loading branch information
nkuba committed Aug 28, 2024
1 parent be2c530 commit 0440580
Show file tree
Hide file tree
Showing 2 changed files with 133 additions and 20 deletions.
9 changes: 6 additions & 3 deletions solidity/contracts/MezoAllocator.sol
Original file line number Diff line number Diff line change
Expand Up @@ -268,9 +268,12 @@ contract MezoAllocator is IDispatcher, Ownable2StepUpgradeable {
.getDeposit(address(this), address(tbtc), depositId)
.balance;

emit DepositReleased(depositId, amount);
depositBalance = 0;
mezoPortal.withdraw(address(tbtc), depositId);
if (amount > 0) {
emit DepositReleased(depositId, amount);
depositBalance = 0;
mezoPortal.withdraw(address(tbtc), depositId);
}

tbtc.safeTransfer(address(stbtc), tbtc.balanceOf(address(this)));
}

Expand Down
144 changes: 127 additions & 17 deletions solidity/test/MezoAllocator.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -733,32 +733,142 @@ describe("MezoAllocator", () => {
})

context("when the caller is governance", () => {
beforeAfterSnapshotWrapper()

context("when there is no deposit", () => {
beforeAfterSnapshotWrapper()

context("when there is no donation", () => {
beforeAfterSnapshotWrapper()

let tx: ContractTransactionResponse

before(async () => {
tx = await mezoAllocator.connect(governance).releaseDeposit()
})

it("should not emit DepositReleased event", async () => {
await expect(tx).to.not.emit(mezoAllocator, "DepositReleased")
})

it("should not call MezoPortal.withdraw function", async () => {
await expect(tx).to.not.emit(mezoPortal, "WithdrawFully")
})
})

context("when there is a donation", () => {
beforeAfterSnapshotWrapper()

const donationAmount = to1e18(2)

let tx: ContractTransactionResponse

before(async () => {
await tbtc.mint(await mezoAllocator.getAddress(), donationAmount)

tx = await mezoAllocator.connect(governance).releaseDeposit()
})

it("should not emit DepositReleased event", async () => {
await expect(tx).to.not.emit(mezoAllocator, "DepositReleased")
})

it("should transfer tBTC to stBTC contract", async () => {
await expect(tx).to.changeTokenBalances(
tbtc,
[mezoAllocator, stbtc],
[-donationAmount, donationAmount],
)
})

it("should not call MezoPortal.withdraw function", async () => {
await expect(tx).to.not.emit(mezoPortal, "WithdrawFully")
})
})
})

context("when there is a deposit", () => {
let tx: ContractTransactionResponse
beforeAfterSnapshotWrapper()

const depositAmount = to1e18(5)

before(async () => {
await tbtc.mint(await stbtc.getAddress(), to1e18(5))
await tbtc.mint(await stbtc.getAddress(), depositAmount)
await mezoAllocator.connect(maintainer).allocate()
tx = await mezoAllocator.connect(governance).releaseDeposit()
})

it("should emit DepositReleased event", async () => {
await expect(tx)
.to.emit(mezoAllocator, "DepositReleased")
.withArgs(1, to1e18(5))
})
context("when there is no donation", () => {
beforeAfterSnapshotWrapper()

let tx: ContractTransactionResponse

before(async () => {
tx = await mezoAllocator.connect(governance).releaseDeposit()
})

it("should emit DepositReleased event", async () => {
await expect(tx)
.to.emit(mezoAllocator, "DepositReleased")
.withArgs(1, depositAmount)
})

it("should decrease tracked deposit balance amount to zero", async () => {
const depositBalance = await mezoAllocator.depositBalance()
expect(depositBalance).to.equal(0)
})

it("should transfer tBTC to stBTC contract", async () => {
await expect(tx).to.changeTokenBalances(
tbtc,
[mezoPortal, stbtc],
[-depositAmount, depositAmount],
)
})

it("should decrease tracked deposit balance amount to zero", async () => {
const depositBalance = await mezoAllocator.depositBalance()
expect(depositBalance).to.equal(0)
it("should call MezoPortal.withdraw function", async () => {
await expect(tx)
.to.emit(mezoPortal, "WithdrawFully")
.withArgs(await tbtc.getAddress(), 1)
})
})

it("should decrease Mezo Portal balance", async () => {
await expect(tx).to.changeTokenBalances(
tbtc,
[mezoPortal, stbtc],
[-to1e18(5), to1e18(5)],
)
context("when there is a donation", () => {
beforeAfterSnapshotWrapper()

const donationAmount = to1e18(2)

let tx: ContractTransactionResponse

before(async () => {
await tbtc.mint(await mezoAllocator.getAddress(), donationAmount)

tx = await mezoAllocator.connect(governance).releaseDeposit()
})

it("should emit DepositReleased event", async () => {
await expect(tx)
.to.emit(mezoAllocator, "DepositReleased")
.withArgs(1, depositAmount)
})

it("should decrease tracked deposit balance amount to zero", async () => {
const depositBalance = await mezoAllocator.depositBalance()
expect(depositBalance).to.equal(0)
})

it("should transfer tBTC to stBTC contract", async () => {
await expect(tx).to.changeTokenBalances(
tbtc,
[mezoPortal, mezoAllocator, stbtc],
[-depositAmount, -donationAmount, depositAmount + donationAmount],
)
})

it("should call MezoPortal.withdraw function", async () => {
await expect(tx)
.to.emit(mezoPortal, "WithdrawFully")
.withArgs(await tbtc.getAddress(), 1)
})
})
})
})
Expand Down

0 comments on commit 0440580

Please sign in to comment.