Skip to content

Commit

Permalink
Engen badges no transfer (#324)
Browse files Browse the repository at this point in the history
* Add transfer restriction in EngenBadges contract by implementing _beforeTokenTransfer hook to allow only minting and burning operations.

* Add tests for single and batch transfer reverts in EngenBadges to ensure transfers are not allowed.

* Upgrade EngenBadges contract to version V4, update deployment scripts and test artifacts, and modify transaction details in JSON files for chain 7887.
  • Loading branch information
ylv-io authored Dec 30, 2024
1 parent c9f2c53 commit 7b2418d
Show file tree
Hide file tree
Showing 6 changed files with 256 additions and 44 deletions.
131 changes: 131 additions & 0 deletions broadcast/116-upgrade_engenbadges.s.sol/7887/run-1735578465.json

Large diffs are not rendered by default.

85 changes: 44 additions & 41 deletions broadcast/116-upgrade_engenbadges.s.sol/7887/run-latest.json

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions script/migrations/116-upgrade_engenbadges.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ contract Script is MigrationHelper {
super.run();

bytes memory bytecode = abi.encodePacked(type(EngenBadges).creationCode);
address impl = _deployImplementationAndUpgrade("EngenBadges", "V3", bytecode, keccak256("V3"));
address impl = _deployImplementationAndUpgrade("EngenBadges", "V4", bytecode, keccak256("V4"));

EngenBadges engenBadges = EngenBadges(_getChainDeployment("EngenBadges"));
uint256[] memory balances = engenBadges.getAllBadges(_getChainDeployment("KintoWallet-admin"), 10);
Expand All @@ -20,6 +20,6 @@ contract Script is MigrationHelper {
assertEq(engenBadges.uri(1), "https://kinto.xyz/api/v1/get-badge-nft/{id}");
assertEq(engenBadges.name(), "Engen Badges");

saveContractAddress("EngenBadgesV3-impl", impl);
saveContractAddress("EngenBadgesV4-impl", impl);
}
}
20 changes: 20 additions & 0 deletions src/tokens/EngenBadges.sol
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ contract EngenBadges is
error MismatchedInputLengths();
error MintToManyAddresses();
error BurnTooManyAddresses();
error TransferNotAllowed();

string public constant name = "Engen Badges";
string public constant symbol = "ENGB";
Expand Down Expand Up @@ -132,6 +133,25 @@ contract EngenBadges is
{
return super.supportsInterface(interfaceId);
}

/**
* @dev Hook that is called before any token transfer. Allow only minting and burning operations.
*/
function _beforeTokenTransfer(
address operator,
address from,
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) internal virtual override {
super._beforeTokenTransfer(operator, from, to, ids, amounts, data);

// Allow minting (from = 0) and burning (to = 0)
if (from != address(0) && to != address(0)) {
revert TransferNotAllowed();
}
}
}

contract EngenBadgesV3 is EngenBadges {
Expand Down
3 changes: 2 additions & 1 deletion test/artifacts/7887/addresses.json
Original file line number Diff line number Diff line change
Expand Up @@ -248,5 +248,6 @@
"KintoIDV10-impl": "0xaa0726829d41E3C70B84Bc5390cce82afC56871A",
"RewardsDistributorV8-impl": "0xF3D955B4cF3489A37027f0F3484E87328dBdBB39",
"KV4-impl": "0xDd11ab74e0e8B042F843447F5754376f2F303492",
"KV5-impl": "0xAf968044D5DE68fE01B5a6517d0DbeE3caD8563a"
"KV5-impl": "0xAf968044D5DE68fE01B5a6517d0DbeE3caD8563a",
"EngenBadgesV4-impl": "0x0b1CcF9bc0ffF49b0fE3Ee4541BF71253C54DE14"
}
57 changes: 57 additions & 0 deletions test/unit/tokens/EngenBadges.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -344,4 +344,61 @@ contract EngenBadgesTest is SharedSetup {
vm.expectRevert(abi.encodeWithSelector(EngenBadges.BurnTooManyAddresses.selector));
_engenBadges.burnBadgesBatch(accounts, ids, amounts);
}

function testTransfer_RevertWhen_SingleTransfer() public {
// First mint a badge to alice
uint256[] memory ids = new uint256[](1);
ids[0] = 1;

UserOperation[] memory userOps = new UserOperation[](1);
userOps[0] = _createUserOperation(
address(_kintoWallet),
address(_engenBadges),
_kintoWallet.getNonce(),
privateKeys,
abi.encodeWithSignature("mintBadges(address,uint256[])", alice, ids),
address(_paymaster)
);

_entryPoint.handleOps(userOps, payable(_owner));
assertEq(_engenBadges.balanceOf(alice, 1), 1);

// Try to transfer from alice to bob
vm.prank(alice);
vm.expectRevert(EngenBadges.TransferNotAllowed.selector);
_engenBadges.safeTransferFrom(alice, bob, 1, 1, "");
}

function testTransfer_RevertWhen_BatchTransfer() public {
// First mint multiple badges to alice
uint256[] memory ids = new uint256[](2);
ids[0] = 1;
ids[1] = 2;

UserOperation[] memory userOps = new UserOperation[](1);
userOps[0] = _createUserOperation(
address(_kintoWallet),
address(_engenBadges),
_kintoWallet.getNonce(),
privateKeys,
abi.encodeWithSignature("mintBadges(address,uint256[])", alice, ids),
address(_paymaster)
);

_entryPoint.handleOps(userOps, payable(_owner));
assertEq(_engenBadges.balanceOf(alice, 1), 1);
assertEq(_engenBadges.balanceOf(alice, 2), 1);

// Try to batch transfer from alice to bob
uint256[] memory transferIds = new uint256[](2);
transferIds[0] = 1;
transferIds[1] = 2;
uint256[] memory amounts = new uint256[](2);
amounts[0] = 1;
amounts[1] = 1;

vm.prank(alice);
vm.expectRevert(EngenBadges.TransferNotAllowed.selector);
_engenBadges.safeBatchTransferFrom(alice, bob, transferIds, amounts, "");
}
}

0 comments on commit 7b2418d

Please sign in to comment.