Skip to content

Commit

Permalink
🚧 update contracts and tests
Browse files Browse the repository at this point in the history
  • Loading branch information
audsssy committed Oct 18, 2023
1 parent 866d5c6 commit 0d6a4e0
Show file tree
Hide file tree
Showing 3 changed files with 121 additions and 90 deletions.
9 changes: 7 additions & 2 deletions src/KaliBerger.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
pragma solidity >=0.8.4;

import {LibString} from "../lib/solbase/src/utils/LibString.sol";
// import {SafeTransferLib} from "../lib/solbase/src/utils/SafeTransferLib.sol";
import {IERC721} from "../lib/forge-std/src/interfaces/IERC721.sol";
import {IERC20} from "../lib/forge-std/src/interfaces/IERC20.sol";

Expand Down Expand Up @@ -341,7 +340,13 @@ contract KaliBerger is Storage {
this.setAddress(keccak256(abi.encode(token, tokenId, ".impactDao")), impactDao);
}

function setTax(address token, uint256 tokenId, uint256 _tax) external payable onlyOperator {
function setTax(address token, uint256 tokenId, uint256 _tax)
external
payable
onlyOperator
collectPatronage(token, tokenId)
{
if (_tax > 100) revert InvalidAmount();
this.setUint(keccak256(abi.encode(token, tokenId, ".tax")), _tax);
}

Expand Down
7 changes: 3 additions & 4 deletions src/tokens/PatronCertificate.sol
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,9 @@ contract PatronCertificate {
/// Metadata Storage/Logic
/// -----------------------------------------------------------------------

string public name;
string public constant name = "Patron Certificate";

string public symbol;
string public constant symbol = "PC";

function tokenURI(uint256 tokenId) public view virtual returns (string memory) {
return _buildURI(tokenId);
Expand Down Expand Up @@ -82,8 +82,6 @@ contract PatronCertificate {
/// -----------------------------------------------------------------------

constructor(address _minter) {
name = "Patron Certificate";
symbol = "PC";
minter = _minter;
}

Expand Down Expand Up @@ -117,6 +115,7 @@ contract PatronCertificate {
function transferFrom(address from, address to, uint256 id) public virtual {
if (to == address(0)) revert InvalidRecipient();

// Minter-only transfer.
if (msg.sender != minter) revert Unauthorized();

// Underflow of the sender's balance is impossible because we check for
Expand Down
195 changes: 111 additions & 84 deletions test/KaliBerger.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ contract KaliBergerTest is Test {
* (block.timestamp - kaliBerger.getTimeLastCollected(address(token), tokenId))
* kaliBerger.getTax(address(token), tokenId) / 365 days / 100;
assertEq(kaliBerger.patronageToCollect(address(token), tokenId), amount);
// emit log_uint(amount);
emit log_uint(amount);
}

/// @notice Anyone can rebalance DAO tokens at any time.
Expand All @@ -171,44 +171,20 @@ contract KaliBergerTest is Test {

// Validate
if (creator == alfred) assertEq(creator_balance, bob_balance + charlie_balance + earn_balance);

// TODO: ACTIVATE OTHER TOKEN PATTERNS TO CONFIRM CONTRACT BALANCES WORK PROPERLY
// if (creator == bob) assertEq(creator_balance, alfred_balance + charlie_balance + earn_balance);
// if (creator == charlie) assertEq(creator_balance, alfred_balance + bob_balance + earn_balance);
emit log_uint(alfred_balance);
emit log_uint(bob_balance);
emit log_uint(charlie_balance);
emit log_uint(earn_balance);
// emit log_uint(alfred_balance);
// emit log_uint(bob_balance);
// emit log_uint(charlie_balance);
// emit log_uint(earn_balance);
}

/// -----------------------------------------------------------------------
/// Test Logic
/// -----------------------------------------------------------------------

/// @notice With KaliBerger uninitialized, Bob tries to buy tokens and gets an Uninitialized() error.
function testUninitialized() public payable {
vm.warp(100);

// Deal Bob ether
vm.deal(bob, 10 ether);

// Bob buys
vm.expectRevert(KaliBerger.NotInitialized.selector);
vm.prank(bob);
kaliBerger.buy{value: 0.1 ether}(address(token_3), 1, 1 ether, 0);
} // timestamp: 1500

/// @notice Charlie tries to escrows tokenId #1 of token_1 and triggers NotAuthorized() error.
function testEscrow_byOthers() public payable {
// Approve KaliBerger to transfer ERC721
vm.prank(alfred);
token_1.approve(address(kaliBerger), 1);
vm.warp(200);

// Charlie escrows Alfred's NFT
vm.expectRevert(KaliBerger.NotAuthorized.selector);
vm.prank(charlie);
kaliBerger.escrow(address(token_1), 1);
}

/// @notice The Gang escrows their tokens.
function testEscrow() public payable {
escrow(alfred, token_1, 1);
Expand All @@ -223,7 +199,7 @@ contract KaliBergerTest is Test {

// DAO approves.
vm.warp(500);
approve(token_1, 1); // 500
approve(token_1, 1); // 500x

// DAO approves.
vm.warp(1000);
Expand Down Expand Up @@ -334,18 +310,6 @@ contract KaliBergerTest is Test {
validatePatronageToCollect(token_1, 1);
} // timestamp: 5000

/// @notice Charlie tries to set a new price and gets an NotAuthorized() error.
function testBuy_setPrice_byOthers() public payable {
// Bob buys.
testBuy();
vm.warp(4500);

// Charlie tries to set new price on behalf of Alfred.
vm.expectRevert(KaliBerger.NotAuthorized.selector);
vm.prank(charlie);
kaliBerger.setPrice(address(token_1), 1, 2 ether);
} // timestamp: 5000

/// @notice Bob add deposits to maintain his ownership of token_1, token #1 for a longer period of time.
function testBuy_addDeposit() public payable {
// Bob buys.
Expand Down Expand Up @@ -376,6 +340,27 @@ contract KaliBergerTest is Test {
assertEq(address(kaliBerger).balance, oldBalance - address(impactDao).balance);
} // timestamp: 4500

/// @notice DAO changes tax
function testBuy_setTax() public payable {
// Bob buys.
testBuy();

// Validate patronage to collect.
vm.warp(6600);
validatePatronageToCollect(token_1, 1);

// Set new tax rate.
vm.prank(dao);
kaliBerger.setTax(address(token_1), 1, 30);

// Validate patronage to collect.
vm.warp(9200);
validatePatronageToCollect(token_1, 1);

// Validate patron balances.
balanceDao(10000, address(token_1), 1, alfred);
}

/// @notice Charlie add deposits to help Bob maintain ownership of token_1, token #1 for a longer period of time.
function testBuy_addDeposit_byOthers() public payable {
// Bob buys.
Expand Down Expand Up @@ -469,30 +454,6 @@ contract KaliBergerTest is Test {
// emit log_uint(address(kaliBerger).balance);
} // timestamp: 6000

/// @notice Bob withdraws too much and triggers InvalidExit() error.
function testBuy_exit_invalidExit() public payable {
// Add deposit.
testBuy_addDeposit();
vm.warp(5000);

// InvalidExit()
vm.expectRevert(KaliBerger.InvalidExit.selector);
vm.prank(bob);
kaliBerger.exit(address(token_1), 1, 1 ether);
}

/// @notice Charlie tries to withdraw from deposit and triggers NotAuthorized() error.
function testBuy_exit_byOthers() public payable {
// Add deposit.
testBuy_addDeposit();
vm.warp(5000);

// InvalidExit()
vm.expectRevert(KaliBerger.NotAuthorized.selector);
vm.prank(charlie);
kaliBerger.exit(address(token_1), 1, 0.2 ether);
}

/// @notice Charlie buys token_1, tokenId #1 and declares new price for sale.
function testBuy_secondBuy() public payable {
// Escrow & approve
Expand Down Expand Up @@ -576,22 +537,6 @@ contract KaliBergerTest is Test {
balanceDao(2707346509, address(token_1), 1, alfred);
} // timestamp: 2707346509

/// @notice Alfred tries to withdraw token_1, tokenId #1 but cannot bc it has not
/// foreclosed yet.
function testBuy_pull_() public payable {
// Continuing from third buy by Earn.
testBuy_secondBuy();

// InvalidExit()
vm.expectRevert(KaliBerger.InvalidExit.selector);
vm.prank(alfred);
kaliBerger.pull(address(token_1), 1);

// Validate
assertEq(token_1.balanceOf(alfred), 0);
assertEq(token_1.balanceOf(address(kaliBerger)), 1);
} // timestamp: 5500

/// @notice Earn buys token_1, tokenId #1 and declares new price for sale.
function testBuy_thirdBuy() public payable {
// Continuing from second buy by Charlie.
Expand Down Expand Up @@ -657,6 +602,88 @@ contract KaliBergerTest is Test {
balanceDao(timestamp, address(token_1), 1, alfred);
} // timestamp: 10000000

/// -----------------------------------------------------------------------
/// Custom Error Test Logic
/// -----------------------------------------------------------------------

/// @notice With KaliBerger uninitialized, Bob tries to buy tokens and gets an Uninitialized() error.
function testUninitialized() public payable {
vm.warp(100);

// Deal Bob ether
vm.deal(bob, 10 ether);

// Bob buys
vm.expectRevert(KaliBerger.NotInitialized.selector);
vm.prank(bob);
kaliBerger.buy{value: 0.1 ether}(address(token_3), 1, 1 ether, 0);
} // timestamp: 1500

/// @notice Charlie tries to escrows tokenId #1 of token_1 and triggers NotAuthorized() error.
function testEscrow_byOthers() public payable {
// Approve KaliBerger to transfer ERC721
vm.prank(alfred);
token_1.approve(address(kaliBerger), 1);
vm.warp(200);

// Charlie escrows Alfred's NFT
vm.expectRevert(KaliBerger.NotAuthorized.selector);
vm.prank(charlie);
kaliBerger.escrow(address(token_1), 1);
}

/// @notice Charlie tries to set a new price and gets an NotAuthorized() error.
function testBuy_setPrice_byOthers() public payable {
// Bob buys.
testBuy();
vm.warp(4500);

// Charlie tries to set new price on behalf of Alfred.
vm.expectRevert(KaliBerger.NotAuthorized.selector);
vm.prank(charlie);
kaliBerger.setPrice(address(token_1), 1, 2 ether);
} // timestamp: 5000

/// @notice Bob withdraws too much and triggers InvalidExit() error.
function testBuy_exit_invalidExit() public payable {
// Add deposit.
testBuy_addDeposit();
vm.warp(5000);

// InvalidExit()
vm.expectRevert(KaliBerger.InvalidExit.selector);
vm.prank(bob);
kaliBerger.exit(address(token_1), 1, 1 ether);
}

/// @notice Charlie tries to withdraw from deposit and triggers NotAuthorized() error.
function testBuy_exit_byOthers() public payable {
// Add deposit.
testBuy_addDeposit();
vm.warp(5000);

// InvalidExit()
vm.expectRevert(KaliBerger.NotAuthorized.selector);
vm.prank(charlie);
kaliBerger.exit(address(token_1), 1, 0.2 ether);
}

/// @notice Alfred tries to withdraw token_1, tokenId #1 but cannot bc it has not
/// foreclosed yet.
function testBuy_pull_() public payable {
// Continuing from third buy by Earn.
testBuy_secondBuy();

// InvalidExit()
vm.expectRevert(KaliBerger.InvalidExit.selector);
vm.prank(alfred);
kaliBerger.pull(address(token_1), 1);

// Validate
assertEq(token_1.balanceOf(alfred), 0);
assertEq(token_1.balanceOf(address(kaliBerger)), 1);
} // timestamp: 5500

/// @notice Earn tries to withdraw token_1, tokenId #1 on behalf of Alfred,
/// @notice but triggers NotAuthorized() error because Alfred is the creator of NFT.
function testBuy_pull_byOthers() public payable {
Expand Down

0 comments on commit 0d6a4e0

Please sign in to comment.