Skip to content

Commit a996917

Browse files
d10rhellwolf
andauthored
[ETHEREUM-CONTRACTS] emit Pseudo Transfer event on flow create/delete and units changing from/to 0 (#2114)
* emit Transfer event on flow create/delete and units changing from/to 0 * don't emit Approval event on transferFrom, refs #2115 * updated CHANGELOG * bumped version to 1.14.0 --------- Co-authored-by: Miao ZhiCheng <miao@superfluid.finance>
1 parent 0097b7b commit a996917

File tree

17 files changed

+118
-34
lines changed

17 files changed

+118
-34
lines changed

packages/automation-contracts/autowrap/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"description": "Open contracts that allow upgrading underlying token to supertokens based on running stream",
44
"version": "0.3.0",
55
"devDependencies": {
6-
"@superfluid-finance/ethereum-contracts": "^1.13.0",
6+
"@superfluid-finance/ethereum-contracts": "^1.14.0",
77
"@superfluid-finance/metadata": "^1.6.2"
88
},
99
"license": "MIT",

packages/automation-contracts/scheduler/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"description": "Open contracts that allow scheduling streams and vestings onchain",
44
"version": "1.3.0",
55
"devDependencies": {
6-
"@superfluid-finance/ethereum-contracts": "^1.13.0",
6+
"@superfluid-finance/ethereum-contracts": "^1.14.0",
77
"@superfluid-finance/metadata": "^1.6.2"
88
},
99
"license": "MIT",

packages/ethereum-contracts/CHANGELOG.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ All notable changes to the ethereum-contracts will be documented in this file.
33

44
This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
55

6-
## [UNRELEASED]
6+
## [v1.14.0]
77

88
### Added
99
- GDA _autoconnect_ feature: now any account can connect pool members using `tryConnectPoolFor()` as long as they have less than 4 connection slots occupied for that Super Token. This allows for smoother onboarding of new users, allowing Apps to make sure tokens distributed via GDA immediately show up in user's wallets. Accounts can opt out of this by using `setConnectPermission()`, this is mainly supposed to be used by contracts.
@@ -15,6 +15,8 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
1515
- `GDAv1StorageWriter` contains functions for writing agreement data to the token contract. This can only be used by the GDA contract itself.
1616
- bump solc to "0.8.30".
1717
- Changed EVM target from `paris` to `shanghai` because now all networks with supported Superfluid deployment support it.
18+
- Emit ERC20 `Transfer` events (with amount 0) on CFA and GDA actions potentially leading to account balance changes. This shall help indexers to keep track of SuperToken holders and account balances.
19+
- Don't emit ERC20 `Approval` events on `transferFrom` operations. This is consistent with the OpenZeppelin ERC20 implementation from v5 onwards. Change effective only for SuperTokens using the latest logic.
1820

1921
### Fixed
2022
- `ISuperfluidPool`: `getClaimable` and `getClaimableNow` could previously return non-zero values for connected pools, which was inconsistent with what `claimAll` would actually do in this situation (claim nothing).

packages/ethereum-contracts/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ If you're building a smart contract that uses Superfluid protocol, or even your
3535
### Installation
3636

3737
Prerequisites:
38-
- [node.js v18+](https://nodejs.org/en/download). The project recommends 22, and is tested with node 18,20,22.
38+
- [node.js v20+](https://nodejs.org/en/download). The project recommends 24, and is tested with node 20,22,24.
3939
- [yarn](https://classic.yarnpkg.com/en/docs/install)
4040
- [forge](https://book.getfoundry.sh/getting-started/installation)
4141

@@ -305,7 +305,7 @@ If you want contribute to Superfluid protocol contracts instead of just interfac
305305

306306
### Setup Development Environment
307307

308-
Prerequisites: You need node.js v18+ and yarn installed.
308+
Prerequisites: You need node.js v20+ and yarn installed.
309309

310310
First, check out this repository and cd into it.
311311
```sh

packages/ethereum-contracts/contracts/agreements/ConstantFlowAgreementV1.sol

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -453,6 +453,8 @@ contract ConstantFlowAgreementV1 is
453453
ctx, currentContext);
454454
}
455455

456+
flowVars.token.emitPseudoTransfer(flowVars.sender, flowVars.receiver);
457+
456458
_requireAvailableBalance(flowVars.token, flowVars.sender, currentContext);
457459
}
458460

@@ -592,6 +594,8 @@ contract ConstantFlowAgreementV1 is
592594
newCtx, currentContext);
593595
}
594596
}
597+
598+
flowVars.token.emitPseudoTransfer(flowVars.sender, flowVars.receiver);
595599
}
596600

597601
/**************************************************************************

packages/ethereum-contracts/contracts/agreements/gdav1/GeneralDistributionAgreementV1.sol

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -801,6 +801,14 @@ contract GeneralDistributionAgreementV1 is AgreementBase, TokenMonad, IGeneralDi
801801
return true;
802802
}
803803

804+
function tokenEmitPseudoTransfer(ISuperfluidToken superToken, address from, address to) external {
805+
if (superToken.isPool(this, msg.sender) == false) {
806+
revert GDA_ONLY_SUPER_TOKEN_POOL();
807+
}
808+
809+
superToken.emitPseudoTransfer(from, to);
810+
}
811+
804812
//////////////////////////////////////////////////////////////////////////////////////////////////////
805813
// TokenMonad interface
806814
//////////////////////////////////////////////////////////////////////////////////////////////////////

packages/ethereum-contracts/contracts/agreements/gdav1/SuperfluidPool.sol

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -453,6 +453,11 @@ contract SuperfluidPool is ISuperfluidPool, BeaconProxiable {
453453
_membersData[memberAddr] = _pdPoolMemberToMemberData(pdPoolMember, claimedValue);
454454
assert(GDA.appendIndexUpdateByPool(superToken, p, t));
455455
}
456+
457+
if ((oldUnits == 0 || newUnits == 0) && oldUnits != newUnits) {
458+
GDA.tokenEmitPseudoTransfer(superToken, address(this), memberAddr);
459+
}
460+
456461
emit MemberUnitsUpdated(superToken, memberAddr, oldUnits, newUnits);
457462
}
458463

packages/ethereum-contracts/contracts/interfaces/superfluid/ISuperfluidToken.sol

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -431,4 +431,11 @@ interface ISuperfluidToken {
431431
uint256 rewardAmount,
432432
uint256 bailoutAmount
433433
);
434+
435+
/**
436+
* @dev Emit an ERC20.Transfer event with zero amount, helps indexers track token holders.
437+
* @param from The address from which the transfer is happening
438+
* @param to The address to which the transfer is happening
439+
*/
440+
function emitPseudoTransfer(address from, address to) external;
434441
}

packages/ethereum-contracts/contracts/superfluid/SuperToken.sol

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -360,7 +360,7 @@ contract SuperToken is
360360
if (spender != holder) {
361361
require(amount <= _allowances[holder][spender], "SuperToken: transfer amount exceeds allowance");
362362
// TODO: this triggers an `Approval` event, which shouldn't happen for transfers.
363-
_approve(holder, spender, _allowances[holder][spender] - amount);
363+
_approve(holder, spender, _allowances[holder][spender] - amount, false);
364364
}
365365

366366
return true;
@@ -504,7 +504,21 @@ contract SuperToken is
504504
* - `account` cannot be the zero address.
505505
* - `spender` cannot be the zero address.
506506
*/
507-
function _approve(address account, address spender, uint256 amount)
507+
function _approve(address owner, address spender, uint256 value) internal {
508+
_approve(owner, spender, value, true);
509+
}
510+
511+
/**
512+
* @dev Variant of {_approve} with an optional flag to enable or disable the {Approval} event.
513+
*
514+
* By default (when calling {_approve}) the flag is set to true. On the other hand, approval changes made
515+
* during the `transferFrom` operation set the flag to false.
516+
*
517+
* Note: In the OpenZeppelin implementation, from v5 onwards, {transferFrom} doesn't emit an {Approval} event.
518+
* By adding this overloaded function and using it for {transferFrom}, we replicate that change,
519+
* because it seems semantically more correct.
520+
*/
521+
function _approve(address account, address spender, uint256 amount, bool emitEvent)
508522
internal
509523
{
510524
if (account == address(0)) {
@@ -515,7 +529,10 @@ contract SuperToken is
515529
}
516530

517531
_allowances[account][spender] = amount;
518-
emit Approval(account, spender, amount);
532+
533+
if (emitEvent) {
534+
emit Approval(account, spender, amount);
535+
}
519536
}
520537

521538
/**

packages/ethereum-contracts/contracts/superfluid/SuperfluidToken.sol

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,10 @@ abstract contract SuperfluidToken is ISuperfluidToken
376376
);
377377
}
378378

379+
function emitPseudoTransfer(address from, address to) external onlyAgreement {
380+
emit IERC20.Transfer(from, to, 0);
381+
}
382+
379383
/**************************************************************************
380384
* Modifiers
381385
*************************************************************************/

0 commit comments

Comments
 (0)