From 2412eb092e704113ecc925b8d863b1aa237ffc08 Mon Sep 17 00:00:00 2001 From: Mark Spanbroek Date: Wed, 15 Jan 2025 10:08:10 +0100 Subject: [PATCH] vault: transfer tokens from one recipient to the other --- contracts/Vault.sol | 17 ++++++++++++++++ test/Vault.tests.js | 49 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+) diff --git a/contracts/Vault.sol b/contracts/Vault.sol index d4cc5c1..5cb4e6f 100644 --- a/contracts/Vault.sol +++ b/contracts/Vault.sol @@ -48,4 +48,21 @@ contract Vault { delete _available[controller][context][recipient]; _token.safeTransfer(address(0xdead), amount); } + + function transfer( + Context context, + Recipient from, + Recipient to, + uint256 amount + ) public { + Controller controller = Controller.wrap(msg.sender); + require( + amount <= _available[controller][context][from], + InsufficientBalance() + ); + _available[controller][context][from] -= amount; + _available[controller][context][to] += amount; + } + + error InsufficientBalance(); } diff --git a/test/Vault.tests.js b/test/Vault.tests.js index b590aba..6328dd1 100644 --- a/test/Vault.tests.js +++ b/test/Vault.tests.js @@ -127,4 +127,53 @@ describe("Vault", function () { expect(after - before).to.equal(amount) }) }) + + describe("transfering", function () { + const context = randomBytes(32) + const amount = 42 + + let other + + beforeEach(async function () { + ;[, , other] = await ethers.getSigners() + await token.connect(account).approve(vault.address, amount) + await vault.deposit(context, account.address, amount) + }) + + it("can transfer tokens from one recipient to the other", async function () { + await vault.transfer(context, account.address, other.address, amount) + expect(await vault.balance(context, account.address)).to.equal(0) + expect(await vault.balance(context, other.address)).to.equal(amount) + }) + + it("can transfer part of a balance", async function () { + await vault.transfer(context, account.address, other.address, 10) + expect(await vault.balance(context, account.address)).to.equal( + amount - 10 + ) + expect(await vault.balance(context, other.address)).to.equal(10) + }) + + it("does not transfer more than the balance", async function () { + await expect( + vault.transfer(context, account.address, other.address, amount + 1) + ).to.be.revertedWith("InsufficientBalance") + }) + + it("can withdraw funds that were transfered in", async function () { + await vault.transfer(context, account.address, other.address, amount) + const before = await token.balanceOf(other.address) + await vault.withdraw(context, other.address) + const after = await token.balanceOf(other.address) + expect(after - before).to.equal(amount) + }) + + it("cannot withdraw funds that were transfered out", async function () { + await vault.transfer(context, account.address, other.address, amount) + const before = await token.balanceOf(account.address) + await vault.withdraw(context, account.address) + const after = await token.balanceOf(account.address) + expect(after).to.equal(before) + }) + }) })