From a5e63ebdc10d91a470c0fe9bf91d1767d61487fe Mon Sep 17 00:00:00 2001 From: zimpha Date: Tue, 10 Dec 2024 11:52:04 +0800 Subject: [PATCH] feat: add events to Profile --- src/interfaces/IProfile.sol | 23 +++++++++++++++++++++++ src/profile/Profile.sol | 17 +++++++++++++++-- test/Profile.t.sol | 28 ++++++++++++++++++++++++++++ 3 files changed, 66 insertions(+), 2 deletions(-) diff --git a/src/interfaces/IProfile.sol b/src/interfaces/IProfile.sol index 074b1c2..df750cb 100644 --- a/src/interfaces/IProfile.sol +++ b/src/interfaces/IProfile.sol @@ -3,6 +3,29 @@ pragma solidity 0.8.19; interface IProfile { + /** + * + * Events * + * + */ + + /// @notice Emitted when a badge is attached. + /// @param uid The id of the badge. + event AttachBadge(bytes32 indexed uid); + + /// @notice Emitted when a badge is detached. + /// @param uid The id of the badge. + event DetachBadge(bytes32 indexed uid); + + /// @notice Emitted when the username is updated. + event ChangeUsername(string oldUsername, string newUsername); + + /// @notice Emitted when the avatar is updated. + event ChangeAvatar(address oldToken, uint256 oldTokenId, address newToken, uint256 newTokenId); + + /// @notice Emitted when the badge order is updated. + event ReorderBadges(uint256 oldOrder, uint256 newOrder); + /** * * Public Mutating Functions * diff --git a/src/profile/Profile.sol b/src/profile/Profile.sol index 16cad3b..83c9661 100644 --- a/src/profile/Profile.sol +++ b/src/profile/Profile.sol @@ -240,16 +240,23 @@ contract Profile is IProfile, Initializable, Multicall { function reorderBadges(uint256[] memory _orders) external onlyOwner { if (_orders.length != uids.length) revert LengthMismatch(); - badgeOrderEncoding = _encodeOrder(_orders); + uint256 oldOrder = badgeOrderEncoding; + uint256 newOrder = _encodeOrder(_orders); + badgeOrderEncoding = newOrder; + + emit ReorderBadges(oldOrder, newOrder); } /// @notice Change the username. /// @param newUsername The new username. function changeUsername(string memory newUsername) external onlyOwner { address _registry = registry; - IProfileRegistry(_registry).unregisterUsername(username); + string memory oldUsername = username; + IProfileRegistry(_registry).unregisterUsername(oldUsername); IProfileRegistry(_registry).registerUsername(newUsername); username = newUsername; + + emit ChangeUsername(oldUsername, newUsername); } /// @notice Change the avatar. @@ -260,7 +267,10 @@ contract Profile is IProfile, Initializable, Multicall { revert TokenNotOwnedByUser(token, tokenId); } + Avatar memory oldAvatar = avatar; avatar = Avatar(token, tokenId); + + emit ChangeAvatar(oldAvatar.token, oldAvatar.tokenId, token, tokenId); } /** @@ -272,6 +282,8 @@ contract Profile is IProfile, Initializable, Multicall { /// @dev Internal function to attach one batch to this profile. /// @param uid The badge uid to attach. function _attachOne(bytes32 uid) private { + // @note This will possible cause re-emit an existing badge, used for off-chain to index any attach tx. + emit AttachBadge(uid); if (indexes[uid] > 0) return; uids.push(uid); @@ -292,6 +304,7 @@ contract Profile is IProfile, Initializable, Multicall { function _detachOne(bytes32 uid) private { uint256 valueIndex = indexes[uid]; if (valueIndex == 0) return; + emit DetachBadge(uid); uint256 length = uids.length; uint256[] memory _oldOrders = _decodeOrder(badgeOrderEncoding, length); diff --git a/test/Profile.t.sol b/test/Profile.t.sol index 1a96f7d..21808e5 100644 --- a/test/Profile.t.sol +++ b/test/Profile.t.sol @@ -57,6 +57,12 @@ contract ProfileRegistryTest is Test { error TokenNotOwnedByUser(address token, uint256 tokenId); error Unauthorized(); + event AttachBadge(bytes32 indexed uid); + event DetachBadge(bytes32 indexed uid); + event ChangeUsername(string oldUsername, string newUsername); + event ChangeAvatar(address oldToken, uint256 oldTokenId, address newToken, uint256 newTokenId); + event ReorderBadges(uint256 oldOrder, uint256 newOrder); + address internal constant attester = address(1); address private constant TREASURY_ADDRESS = 0x1000000000000000000000000000000000000000; @@ -114,6 +120,10 @@ contract ProfileRegistryTest is Test { bytes32[] memory uids = new bytes32[](2); uids[0] = uid0; uids[1] = uid1; + vm.expectEmit(false, false, false, true, address(profile)); + emit AttachBadge(uid0); + vm.expectEmit(false, false, false, true, address(profile)); + emit AttachBadge(uid1); profile.attach(uids); bytes32[] memory badges = profile.getAttachedBadges(); assertEq(badges.length, 2); @@ -129,6 +139,10 @@ contract ProfileRegistryTest is Test { assertEq(orders[1], 2); // attach again, no op + vm.expectEmit(false, false, false, true, address(profile)); + emit AttachBadge(uid0); + vm.expectEmit(false, false, false, true, address(profile)); + emit AttachBadge(uid1); profile.attach(uids); badges = profile.getAttachedBadges(); assertEq(badges.length, 2); @@ -231,6 +245,8 @@ contract ProfileRegistryTest is Test { // detach 6, order would be: 1, 2, 3, 4, 5, 9, 6, 7, 8 bytes32[] memory detachBadges = new bytes32[](1); detachBadges[0] = originalBadges[5]; + vm.expectEmit(false, false, false, true, address(profile)); + emit DetachBadge(originalBadges[5]); profile.detach(detachBadges); bytes32[] memory badges = profile.getAttachedBadges(); assertEq(badges.length, 9); @@ -252,6 +268,14 @@ contract ProfileRegistryTest is Test { detachBadges[1] = badges[1]; detachBadges[2] = badges[2]; detachBadges[3] = badges[3]; + vm.expectEmit(false, false, false, true, address(profile)); + emit DetachBadge(badges[0]); + vm.expectEmit(false, false, false, true, address(profile)); + emit DetachBadge(badges[1]); + vm.expectEmit(false, false, false, true, address(profile)); + emit DetachBadge(badges[2]); + vm.expectEmit(false, false, false, true, address(profile)); + emit DetachBadge(badges[3]); profile.detach(detachBadges); badges = profile.getAttachedBadges(); assertEq(badges.length, 5); @@ -353,6 +377,8 @@ contract ProfileRegistryTest is Test { // succeed assertEq(profile.username(), "xxxxx"); + vm.expectEmit(false, false, false, true, address(profile)); + emit ChangeUsername("xxxxx", "zzzzz"); profile.changeUsername("zzzzz"); assertEq(profile.username(), "zzzzz"); } @@ -375,6 +401,8 @@ contract ProfileRegistryTest is Test { // succeed assertEq(profile.getAvatar(), "123"); + vm.expectEmit(false, false, false, true, address(profile)); + emit ChangeAvatar(address(0), 0, address(token), 1); profile.changeAvatar(address(token), 1); assertEq(profile.getAvatar(), "testBaseURI/1");