Skip to content

Commit

Permalink
fix: contract and add test_flow
Browse files Browse the repository at this point in the history
  • Loading branch information
johnson86tw committed Jan 10, 2025
1 parent e1bf036 commit 98af9fa
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 23 deletions.
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,6 @@ Submitter
- 領取稿費

## Reference
- erc7579-imple
- ecdsavalidator

- https://github.com/consenlabs/ethtaipei2023-aa-workshop
- https://github.com/erc7579/erc7579-implementation
28 changes: 14 additions & 14 deletions src/RoyaltyAutoClaim.sol
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,9 @@ contract RoyaltyAutoClaim is UUPSUpgradeable, OwnableUpgradeable, IAccount {
error AlreadyClaimed();
error RenounceOwnershipDisabled();
error SubmissionNotExist();
error NotClaimable();
error NotFromEntryPoint();
error ForbiddenPaymaster();
error ZeroRoyalty();

uint8 public constant ROYALTY_LEVEL_20 = 20;
uint8 public constant ROYALTY_LEVEL_40 = 40;
Expand All @@ -52,7 +52,7 @@ contract RoyaltyAutoClaim is UUPSUpgradeable, OwnableUpgradeable, IAccount {
}

mapping(string => Submission) public submissions;
mapping(string => bool) public claimed;
mapping(string => bool) public isClaimed;

constructor() {
_disableInitializers();
Expand Down Expand Up @@ -178,10 +178,13 @@ contract RoyaltyAutoClaim is UUPSUpgradeable, OwnableUpgradeable, IAccount {
// TODO: add ReentrancyGuard
function claimRoyalty(string memory title) public {
require(isSubmissionExist(title), SubmissionNotExist());
require(isSubmissionClaimable(title), NotClaimable());
uint256 royaltyAmount = getRoyalty(title);
claimed[title] = true;
IERC20(token).safeTransfer(submissions[title].royaltyRecipient, royaltyAmount);
require(!isClaimed[title], AlreadyClaimed());
require(isSubmissionClaimable(title), NotEnoughReviews());
uint256 amount = getRoyalty(title);
require(amount > 0, ZeroRoyalty());

isClaimed[title] = true;
IERC20(token).safeTransfer(submissions[title].royaltyRecipient, amount);
}

// ================================ View ================================
Expand All @@ -191,20 +194,17 @@ contract RoyaltyAutoClaim is UUPSUpgradeable, OwnableUpgradeable, IAccount {
}

function isSubmissionClaimable(string memory title) public view returns (bool) {
if (!isSubmissionExist(title) || claimed[title]) {
if (!isSubmissionExist(title) || isClaimed[title]) {
return false;
}
return submissions[title].reviewCount >= 2 && getRoyalty(title) > 0;
return submissions[title].reviewCount >= 2;
}

function getRoyalty(string memory title) public view returns (uint256 royalty) {
require(isSubmissionExist(title), SubmissionNotExist());
Submission memory submission = submissions[title];
if (submission.reviewCount == 0) {
return 0;
}
if (!isSubmissionClaimable(title)) return 0;

// TODO: add multiplier variable or just use 1e18?
return (submission.totalRoyaltyLevel * 1e18) / submission.reviewCount;
return (uint256(submissions[title].totalRoyaltyLevel) * 1e18) / submissions[title].reviewCount;
}

/**
Expand Down
68 changes: 61 additions & 7 deletions test/RoyaltyAutoClaim.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,39 +4,57 @@ pragma solidity ^0.8.27;
import "../src/RoyaltyAutoClaim.sol";
import "./MockV2.sol";
import "./AATest.t.sol";
import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol";

contract MockERC20 is ERC20 {
constructor(address owner) ERC20("Test", "TEST") {
_mint(owner, 100 ether);
}
}

contract RoyaltyAutoClaimTest is AATest {
RoyaltyAutoClaim royaltyAutoClaim;
address owner = vm.addr(1);
address admin = vm.addr(2);
address token = vm.addr(3);
address[] reviewers = new address[](3);

RoyaltyAutoClaim royaltyAutoClaim;
UUPSProxy proxy;
IERC20 token;

function setUp() public override {
super.setUp();

reviewers[0] = vm.addr(4);
reviewers[1] = vm.addr(5);
reviewers[2] = vm.addr(6);
reviewers[0] = vm.addr(3);
reviewers[1] = vm.addr(4);

token = new MockERC20(owner);

royaltyAutoClaim = new RoyaltyAutoClaim();
proxy = new UUPSProxy(
address(royaltyAutoClaim), abi.encodeCall(RoyaltyAutoClaim.initialize, (owner, admin, token, reviewers))
address(royaltyAutoClaim),
abi.encodeCall(RoyaltyAutoClaim.initialize, (owner, admin, address(token), reviewers))
);

bytes32 v = vm.load(address(proxy), ERC1967Utils.IMPLEMENTATION_SLOT);
assertEq(address(uint160(uint256(v))), address(royaltyAutoClaim));

// deal
vm.deal(address(proxy), 100 ether);
vm.prank(owner);
token.transfer(address(proxy), 100 ether);

// log
console.log("owner", owner);
console.log("admin", admin);
console.log("reviewer 0", reviewers[0]);
console.log("reviewer 1", reviewers[1]);
}

function test_upgradeToAndCall() public {
address newOwner = vm.randomAddress();
MockV2 v2 = new MockV2();

vm.prank(vm.addr(123));
vm.prank(vm.addr(0xbeef));
vm.expectRevert();
MockV2(address(proxy)).upgradeToAndCall(address(v2), abi.encodeCall(MockV2.initialize, (newOwner)));

Expand Down Expand Up @@ -85,4 +103,40 @@ contract RoyaltyAutoClaimTest is AATest {

assertEq(address(uint160(uint256(vm.load(address(proxy), ERC1967Utils.IMPLEMENTATION_SLOT)))), address(v2));
}

function test_flow() public {
address submitter = vm.randomAddress();
vm.prank(admin);
RoyaltyAutoClaim(address(proxy)).registerSubmission("test", submitter);

(address royaltyRecipient, uint8 reviewCount, uint16 totalRoyaltyLevel) =
RoyaltyAutoClaim(address(proxy)).submissions("test");
assertEq(royaltyRecipient, submitter);
assertEq(reviewCount, 0);
assertEq(totalRoyaltyLevel, 0);

vm.expectRevert();
RoyaltyAutoClaim(address(proxy)).claimRoyalty("test");

vm.prank(reviewers[0]);
RoyaltyAutoClaim(address(proxy)).reviewSubmission("test", 20);

vm.expectRevert();
RoyaltyAutoClaim(address(proxy)).claimRoyalty("test");
assertEq(RoyaltyAutoClaim(address(proxy)).getRoyalty("test"), 0 ether);

vm.prank(reviewers[1]);
RoyaltyAutoClaim(address(proxy)).reviewSubmission("test", 40);

assertEq(RoyaltyAutoClaim(address(proxy)).getRoyalty("test"), 30 ether);

uint256 proxyBalanceBefore = token.balanceOf(address(proxy));

RoyaltyAutoClaim(address(proxy)).claimRoyalty("test");

uint256 proxyBalanceAfter = token.balanceOf(address(proxy));

assertEq(token.balanceOf(submitter), 30 ether);
assertEq(proxyBalanceAfter, proxyBalanceBefore - 30 ether);
}
}

0 comments on commit 98af9fa

Please sign in to comment.