pragma solidity 0.8.18;
import {Test, console} from "forge-std/Test.sol";
import {ProxyFactory} from "../src/ProxyFactory.sol";
import {Distributor} from "../src/Distributor.sol";
import {MockERC20Blacklisted} from "./mock/MockERC20Blacklisted.sol";
contract TestPoc is Test {
ProxyFactory public proxyFactory;
Distributor public distributor;
MockERC20Blacklisted public token;
address public sponsor;
address public organizer;
address public user;
address public user2;
address public user3;
uint256 tokenAmount = 1_000_000 * 1e18;
uint256 tokenAmountAfterPayout = 950_000 * 1e18;
function setUp() public {
sponsor = address(2);
organizer = address(3);
user = address(4);
user2 = address(5);
user3 = address(6);
token = new MockERC20Blacklisted("Test", "TST");
token.mint(sponsor, tokenAmount);
address[] memory whitelisted = new address[](1);
whitelisted[0] = address(token);
proxyFactory = new ProxyFactory(whitelisted);
distributor = new Distributor(address(proxyFactory), address(1));
token.addToBlackList(user3);
}
function testSetUp() public {
assertTrue(address(token) != address(0));
assertEq(token.balanceOf(sponsor), tokenAmount);
assertTrue(address(proxyFactory) != address(0));
assertEq(proxyFactory.whitelistedTokens(address(token)), true);
assertTrue(address(distributor) != address(0));
(address factory, address feeAddress,,) = distributor.getConstants();
assertEq(address(proxyFactory), factory);
assertEq(address(1), feeAddress);
assertEq(sponsor, address(2));
assertEq(organizer, address(3));
assertEq(user, address(4));
assertEq(token.isBlacklisted(user3), true);
}
function testBlacklistedUser() public {
address proxyContestAddress = proxyFactory.getProxyAddress(_calculateSalt(organizer, bytes32("1"), address(distributor)), address(distributor));
vm.prank(sponsor);
token.transfer(proxyContestAddress, tokenAmount);
assertEq(token.balanceOf(proxyContestAddress), tokenAmount);
proxyFactory.setContest(organizer, bytes32("1"), block.timestamp + 1, address(distributor));
skip(10);
bytes memory data = createData();
vm.startPrank(organizer);
vm.expectRevert();
proxyFactory.deployProxyAndDistribute(bytes32("1"), address(distributor), data);
vm.stopPrank();
console.log("--------------------------------------");
console.log("Users balances:");
console.log("User 1 balance", token.balanceOf(user));
console.log("User 2 balance", token.balanceOf(user2));
console.log("User 3 balance", token.balanceOf(user3));
console.log("Is user 3 blacklisted:", token.isBlacklisted(user3));
}
function createData() public view returns (bytes memory data) {
address[] memory winners = new address[](3);
winners[0] = user;
winners[1] = user2;
winners[2] = user3;
uint256[] memory percentages_ = new uint256[](3);
percentages_[0] = 4500;
percentages_[1] = 3000;
percentages_[2] = 2000;
data = abi.encodeWithSelector(Distributor.distribute.selector, address(token), winners, percentages_, "");
}
function _calculateSalt(address _organizer, bytes32 _contestId, address _implementation)
internal
pure
returns (bytes32)
{
return keccak256(abi.encode(_organizer, _contestId, _implementation));
}
}
pragma solidity 0.8.18;
import {ERC20} from "openzeppelin/token/ERC20/ERC20.sol";
import {Ownable} from "openzeppelin/access/Ownable.sol";
contract MockERC20Blacklisted is ERC20, Ownable {
error MockERC20Blacklisted__AmountMustBeMoreThanZero();
error MockERC20Blacklisted__BlacklistAddress();
mapping(address => bool) public isBlacklisted;
constructor(string memory name, string memory symbol) ERC20(name, symbol) {
_mint(msg.sender, 100000 * 10 ** decimals());
}
function mint(address _to, uint256 _amount) external onlyOwner returns (bool) {
if (_amount == 0) {
revert MockERC20Blacklisted__AmountMustBeMoreThanZero();
}
_mint(_to, _amount);
return true;
}
function _beforeTokenTransfer(
address from,
address to,
uint256
) internal virtual override {
if (isBlacklisted[from] == true || isBlacklisted[to] == true) {
revert MockERC20Blacklisted__BlacklistAddress();
}
}
function addToBlackList(address _blacklistedAddress) public onlyOwner {
isBlacklisted[_blacklistedAddress] = true;
}
}
This issue can cause DoS or prevent user from receiving his prize.
Implement check mechanism to ensure that all of the users (supporters) are allowed to receive prize in desired token. If not allow user to provide other address.