Skip to content

Commit

Permalink
loot fixes and tests
Browse files Browse the repository at this point in the history
  • Loading branch information
ipatka committed Feb 16, 2022
1 parent 80c32a3 commit 0296fc7
Show file tree
Hide file tree
Showing 4 changed files with 377 additions and 81 deletions.
15 changes: 10 additions & 5 deletions contracts/LootERC20.sol
Original file line number Diff line number Diff line change
Expand Up @@ -31,20 +31,23 @@ contract Loot is ERC20, Initializable {
);

// Baal Config
IBaal baal;
IBaal public baal;

modifier baalOnly() {
require(msg.sender == address(baal), "!auth");
_;
}

constructor() ERC20("Template", "T") {} /*Configure template to be unusable*/
constructor() ERC20("Template", "T") initializer {} /*Configure template to be unusable*/

/// @notice Configure loot - called by Baal on summon
/// @dev initializer should prevent this from being called again
/// @param name_ Name for ERC20 token trackers
/// @param symbol_ Symbol for ERC20 token trackers
function setUp(string memory name_, string memory symbol_) public initializer {
function setUp(string memory name_, string memory symbol_)
public
initializer
{
baal = IBaal(msg.sender); /*Configure Baal to setup sender*/
_name = name_;
_symbol = symbol_;
Expand Down Expand Up @@ -80,7 +83,6 @@ contract Loot is ERC20, Initializable {
return true;
}


/// @notice Baal-only function to mint loot.
/// @param recipient Address to receive loot
/// @param amount Amount to mint
Expand Down Expand Up @@ -143,6 +145,7 @@ contract Loot is ERC20, Initializable {
}

/// @notice Internal hook to restrict token transfers unless allowed by baal
/// @dev Allows transfers if msg.sender is Baal which enables minting and burning
/// @param from The address of the source account.
/// @param to The address of the destination account.
/// @param amount The number of `loot` tokens to transfer.
Expand All @@ -153,7 +156,9 @@ contract Loot is ERC20, Initializable {
) internal override(ERC20) {
super._beforeTokenTransfer(from, to, amount);
require(
from == address(0) || to == address(0) || !baal.lootPaused(),
from == address(0) || /*Minting allowed*/
(msg.sender == address(baal) && to == address(0)) || /*Burning by Baal allowed*/
!baal.lootPaused(),
"!transferable"
);
}
Expand Down
33 changes: 33 additions & 0 deletions contracts/mock/MockBaal.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity >=0.8.0;

import "../Baal.sol";

contract MockBaal is CloneFactory {
bool public lootPaused;
ILoot public lootToken; /*Sub ERC20 for loot mgmt*/

constructor(
address payable _lootSingleton,
string memory _name,
string memory _symbol
) {
lootToken = ILoot(createClone(_lootSingleton)); /*Clone loot singleton using EIP1167 minimal proxy pattern*/
lootToken.setUp(
string(abi.encodePacked(_name, " LOOT")),
string(abi.encodePacked(_symbol, "-LOOT"))
);
}

function setLootPaused(bool paused) external {
lootPaused = paused;
}

function mintLoot(address _to, uint256 _amount) external {
lootToken.mint(_to, _amount);
}

function burnLoot(address _from, uint256 _amount) external {
lootToken.burn(_from, _amount);
}
}
76 changes: 0 additions & 76 deletions test/Baal.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1503,82 +1503,6 @@ describe('Baal contract', function () {
})
})

describe('erc20 loot - increase allowance with permit', function() {
it('increase allowance with valid permit', async function() {
const deadline = await blockTime() + 10000
const nonce = await lootToken.nonces(summoner.address)
const permitSignature = await signPermit(chainId,lootToken.address, summoner, await lootToken.name(), summoner.address, shaman.address,500,nonce,deadline)
await lootToken.permit(summoner.address, shaman.address, 500, deadline,permitSignature)
const shamanAllowance = await lootToken.allowance(summoner.address, shaman.address)
expect(shamanAllowance).to.equal(500)
})

it('Require fail - invalid nonce', async function() {
const deadline = await blockTime() + 10000
const nonce = await lootToken.nonces(summoner.address)
const permitSignature = await signPermit(chainId,lootToken.address, summoner, await lootToken.name(), summoner.address, shaman.address,500,nonce.add(1),deadline)
expect(lootToken.permit(summoner.address, shaman.address, 500, deadline,permitSignature)).to.be.revertedWith(revertMessages.permitNotAuthorized)
})

it('Require fail - invalid chain Id', async function() {
const deadline = await blockTime() + 10000
const nonce = await lootToken.nonces(summoner.address)
const permitSignature = await signPermit(420,lootToken.address, summoner, await lootToken.name(), summoner.address, shaman.address,500,nonce,deadline)
expect(lootToken.permit(summoner.address, shaman.address, 500, deadline,permitSignature)).to.be.revertedWith(revertMessages.permitNotAuthorized)
})

it('Require fail - invalid name', async function() {
const deadline = await blockTime() + 10000
const nonce = await lootToken.nonces(summoner.address)
const permitSignature = await signPermit(chainId,lootToken.address, summoner, 'invalid', summoner.address, shaman.address,500,nonce,deadline)
expect(lootToken.permit(summoner.address, shaman.address, 500, deadline,permitSignature)).to.be.revertedWith(revertMessages.permitNotAuthorized)
})

it('Require fail - invalid address', async function() {
const deadline = await blockTime() + 10000
const nonce = await lootToken.nonces(summoner.address)
const permitSignature = await signPermit(chainId,zeroAddress, summoner, await lootToken.name(), summoner.address, shaman.address,500,nonce,deadline)
expect(lootToken.permit(summoner.address, shaman.address, 500, deadline,permitSignature)).to.be.revertedWith(revertMessages.permitNotAuthorized)
})

it('Require fail - invalid owner', async function() {
const deadline = await blockTime() + 10000
const nonce = await lootToken.nonces(summoner.address)
const permitSignature = await signPermit(chainId,lootToken.address, summoner, await lootToken.name(), s1.address, shaman.address,500,nonce,deadline)
expect(lootToken.permit(summoner.address, shaman.address, 500, deadline,permitSignature)).to.be.revertedWith(revertMessages.permitNotAuthorized)
})

it('Require fail - invalid spender', async function() {
const deadline = await blockTime() + 10000
const nonce = await lootToken.nonces(summoner.address)
const permitSignature = await signPermit(chainId,lootToken.address, summoner, await lootToken.name(), summoner.address, s1.address,500,nonce,deadline)
expect(lootToken.permit(summoner.address, shaman.address, 500, deadline,permitSignature)).to.be.revertedWith(revertMessages.permitNotAuthorized)
})

it('Require fail - invalid amount', async function() {
const deadline = await blockTime() + 10000
const nonce = await lootToken.nonces(summoner.address)
const permitSignature = await signPermit(chainId,lootToken.address, summoner, await lootToken.name(), summoner.address, shaman.address,499,nonce,deadline)
expect(lootToken.permit(summoner.address, shaman.address, 500, deadline,permitSignature)).to.be.revertedWith(revertMessages.permitNotAuthorized)
})

it('Require fail - invalid deadline', async function() {
const deadline = await blockTime() + 10000
const nonce = await lootToken.nonces(summoner.address)
const permitSignature = await signPermit(chainId,lootToken.address, summoner, await lootToken.name(), summoner.address, shaman.address,500,nonce,deadline - 1)
expect(lootToken.permit(summoner.address, shaman.address, 500, deadline,permitSignature)).to.be.revertedWith(revertMessages.permitNotAuthorized)
})

it('Require fail - expired deadline', async function() {
const deadline = await blockTime() - 1
const nonce = await lootToken.nonces(summoner.address)
const permitSignature = await signPermit(chainId,lootToken.address, summoner, await lootToken.name(), summoner.address, shaman.address,500,nonce,deadline)
expect(lootToken.permit(summoner.address, shaman.address, 500, deadline,permitSignature)).to.be.revertedWith(revertMessages.permitExpired)
})

})


describe('submitProposal', function () {
it('happy case', async function () {
// note - this also tests that members can submit proposals without offering tribute
Expand Down
Loading

0 comments on commit 0296fc7

Please sign in to comment.