mirror of
https://github.com/logos-storage/logos-storage-contracts-eth.git
synced 2026-01-09 08:43:08 +00:00
vault: designate tokens for a single recipient
This commit is contained in:
parent
7018f9ef22
commit
e1f914726b
@ -15,6 +15,8 @@ contract Vault {
|
||||
|
||||
mapping(Controller => mapping(Context => mapping(Recipient => uint256)))
|
||||
private _available;
|
||||
mapping(Controller => mapping(Context => mapping(Recipient => uint256)))
|
||||
private _designated;
|
||||
|
||||
constructor(IERC20 token) {
|
||||
_token = token;
|
||||
@ -25,7 +27,17 @@ contract Vault {
|
||||
Recipient recipient
|
||||
) public view returns (uint256) {
|
||||
Controller controller = Controller.wrap(msg.sender);
|
||||
return _available[controller][context][recipient];
|
||||
return
|
||||
_available[controller][context][recipient] +
|
||||
_designated[controller][context][recipient];
|
||||
}
|
||||
|
||||
function designated(
|
||||
Context context,
|
||||
Recipient recipient
|
||||
) public view returns (uint256) {
|
||||
Controller controller = Controller.wrap(msg.sender);
|
||||
return _designated[controller][context][recipient];
|
||||
}
|
||||
|
||||
function deposit(Context context, address from, uint256 amount) public {
|
||||
@ -35,17 +47,21 @@ contract Vault {
|
||||
_token.safeTransferFrom(from, address(this), amount);
|
||||
}
|
||||
|
||||
function withdraw(Context context, Recipient recipient) public {
|
||||
function _delete(Context context, Recipient recipient) private {
|
||||
Controller controller = Controller.wrap(msg.sender);
|
||||
uint256 amount = _available[controller][context][recipient];
|
||||
delete _available[controller][context][recipient];
|
||||
delete _designated[controller][context][recipient];
|
||||
}
|
||||
|
||||
function withdraw(Context context, Recipient recipient) public {
|
||||
uint256 amount = balance(context, recipient);
|
||||
_delete(context, recipient);
|
||||
_token.safeTransfer(Recipient.unwrap(recipient), amount);
|
||||
}
|
||||
|
||||
function burn(Context context, Recipient recipient) public {
|
||||
Controller controller = Controller.wrap(msg.sender);
|
||||
uint256 amount = _available[controller][context][recipient];
|
||||
delete _available[controller][context][recipient];
|
||||
uint256 amount = balance(context, recipient);
|
||||
_delete(context, recipient);
|
||||
_token.safeTransfer(address(0xdead), amount);
|
||||
}
|
||||
|
||||
@ -64,5 +80,19 @@ contract Vault {
|
||||
_available[controller][context][to] += amount;
|
||||
}
|
||||
|
||||
function designate(
|
||||
Context context,
|
||||
Recipient recipient,
|
||||
uint256 amount
|
||||
) public {
|
||||
Controller controller = Controller.wrap(msg.sender);
|
||||
require(
|
||||
amount <= _available[controller][context][recipient],
|
||||
InsufficientBalance()
|
||||
);
|
||||
_available[controller][context][recipient] -= amount;
|
||||
_designated[controller][context][recipient] += amount;
|
||||
}
|
||||
|
||||
error InsufficientBalance();
|
||||
}
|
||||
|
||||
@ -38,7 +38,7 @@ describe("Vault", function () {
|
||||
await expect(depositing).to.be.revertedWith("insufficient allowance")
|
||||
})
|
||||
|
||||
it("multiple deposits add to the balance", async function () {
|
||||
it("adds multiple deposits to the balance", async function () {
|
||||
await token.connect(account).approve(vault.address, amount)
|
||||
await vault.deposit(context, account.address, amount / 2)
|
||||
await vault.deposit(context, account.address, amount / 2)
|
||||
@ -132,48 +132,136 @@ describe("Vault", function () {
|
||||
const context = randomBytes(32)
|
||||
const amount = 42
|
||||
|
||||
let other
|
||||
let account2
|
||||
let account3
|
||||
|
||||
beforeEach(async function () {
|
||||
;[, , other] = await ethers.getSigners()
|
||||
;[, , account2, account3] = 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)
|
||||
await vault.transfer(context, account.address, account2.address, amount)
|
||||
expect(await vault.balance(context, account.address)).to.equal(0)
|
||||
expect(await vault.balance(context, other.address)).to.equal(amount)
|
||||
expect(await vault.balance(context, account2.address)).to.equal(amount)
|
||||
})
|
||||
|
||||
it("can transfer part of a balance", async function () {
|
||||
await vault.transfer(context, account.address, other.address, 10)
|
||||
await vault.transfer(context, account.address, account2.address, 10)
|
||||
expect(await vault.balance(context, account.address)).to.equal(
|
||||
amount - 10
|
||||
)
|
||||
expect(await vault.balance(context, other.address)).to.equal(10)
|
||||
expect(await vault.balance(context, account2.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)
|
||||
vault.transfer(context, account.address, account2.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)
|
||||
await vault.transfer(context, account.address, account2.address, amount)
|
||||
const before = await token.balanceOf(account2.address)
|
||||
await vault.withdraw(context, account2.address)
|
||||
const after = await token.balanceOf(account2.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)
|
||||
await vault.transfer(context, account.address, account2.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)
|
||||
})
|
||||
|
||||
it("can transfer out funds that were transfered in", async function () {
|
||||
await vault.transfer(context, account.address, account2.address, amount)
|
||||
await vault.transfer(context, account2.address, account3.address, amount)
|
||||
expect(await vault.balance(context, account2.address)).to.equal(0)
|
||||
expect(await vault.balance(context, account3.address)).to.equal(amount)
|
||||
})
|
||||
})
|
||||
|
||||
describe("designating", async function () {
|
||||
const context = randomBytes(32)
|
||||
const amount = 42
|
||||
|
||||
let account2
|
||||
|
||||
beforeEach(async function () {
|
||||
;[, , account2] = await ethers.getSigners()
|
||||
await token.connect(account).approve(vault.address, amount)
|
||||
await vault.deposit(context, account.address, amount)
|
||||
})
|
||||
|
||||
it("can designate tokens for a single recipient", async function () {
|
||||
await vault.designate(context, account.address, amount)
|
||||
expect(await vault.designated(context, account.address)).to.equal(amount)
|
||||
})
|
||||
|
||||
it("can designate part of the balance", async function () {
|
||||
await vault.designate(context, account.address, 10)
|
||||
expect(await vault.designated(context, account.address)).to.equal(10)
|
||||
})
|
||||
|
||||
it("adds up designated tokens", async function () {
|
||||
await vault.designate(context, account.address, 10)
|
||||
await vault.designate(context, account.address, 10)
|
||||
expect(await vault.designated(context, account.address)).to.equal(20)
|
||||
})
|
||||
|
||||
it("cannot designate more than the undesignated balance", async function () {
|
||||
await vault.designate(context, account.address, amount)
|
||||
await expect(
|
||||
vault.designate(context, account.address, 1)
|
||||
).to.be.revertedWith("InsufficientBalance")
|
||||
})
|
||||
|
||||
it("does not change the balance", async function () {
|
||||
await vault.designate(context, account.address, 10)
|
||||
expect(await vault.balance(context, account.address)).to.equal(amount)
|
||||
})
|
||||
|
||||
it("does not allow designated tokens to be transfered", async function () {
|
||||
await vault.designate(context, account.address, 1)
|
||||
await expect(
|
||||
vault.transfer(context, account.address, account2.address, amount)
|
||||
).to.be.revertedWith("InsufficientBalance")
|
||||
})
|
||||
|
||||
it("allows designated tokens to be withdrawn", async function () {
|
||||
await vault.designate(context, account.address, 10)
|
||||
const before = await token.balanceOf(account.address)
|
||||
await vault.withdraw(context, account.address)
|
||||
const after = await token.balanceOf(account.address)
|
||||
expect(after - before).to.equal(amount)
|
||||
})
|
||||
|
||||
it("does not withdraw designated tokens more than once", async function () {
|
||||
await vault.designate(context, account.address, 10)
|
||||
await vault.withdraw(context, account.address)
|
||||
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)
|
||||
})
|
||||
|
||||
it("allows designated tokens to be burned", async function () {
|
||||
await vault.designate(context, account.address, 10)
|
||||
await vault.burn(context, account.address)
|
||||
expect(await vault.balance(context, account.address)).to.equal(0)
|
||||
})
|
||||
|
||||
it("moves burned designated tokens to address 0xdead", async function () {
|
||||
const dead = "0x000000000000000000000000000000000000dead"
|
||||
await vault.designate(context, account.address, 10)
|
||||
const before = await token.balanceOf(dead)
|
||||
await vault.burn(context, account.address)
|
||||
const after = await token.balanceOf(dead)
|
||||
expect(after - before).to.equal(amount)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user