Unverified Commit 8a775cd8 by Hadrien Croubois Committed by GitHub

Emit DelegateVotesChanged events after Transfer (#2733)

parent 4d0f8c1d
...@@ -234,6 +234,8 @@ contract ERC20 is Context, IERC20, IERC20Metadata { ...@@ -234,6 +234,8 @@ contract ERC20 is Context, IERC20, IERC20Metadata {
_balances[recipient] += amount; _balances[recipient] += amount;
emit Transfer(sender, recipient, amount); emit Transfer(sender, recipient, amount);
_afterTokenTransfer(sender, recipient, amount);
} }
/** @dev Creates `amount` tokens and assigns them to `account`, increasing /** @dev Creates `amount` tokens and assigns them to `account`, increasing
...@@ -253,6 +255,8 @@ contract ERC20 is Context, IERC20, IERC20Metadata { ...@@ -253,6 +255,8 @@ contract ERC20 is Context, IERC20, IERC20Metadata {
_totalSupply += amount; _totalSupply += amount;
_balances[account] += amount; _balances[account] += amount;
emit Transfer(address(0), account, amount); emit Transfer(address(0), account, amount);
_afterTokenTransfer(address(0), account, amount);
} }
/** /**
...@@ -279,6 +283,8 @@ contract ERC20 is Context, IERC20, IERC20Metadata { ...@@ -279,6 +283,8 @@ contract ERC20 is Context, IERC20, IERC20Metadata {
_totalSupply -= amount; _totalSupply -= amount;
emit Transfer(account, address(0), amount); emit Transfer(account, address(0), amount);
_afterTokenTransfer(account, address(0), amount);
} }
/** /**
...@@ -313,7 +319,7 @@ contract ERC20 is Context, IERC20, IERC20Metadata { ...@@ -313,7 +319,7 @@ contract ERC20 is Context, IERC20, IERC20Metadata {
* Calling conditions: * Calling conditions:
* *
* - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
* will be to transferred to `to`. * will be transferred to `to`.
* - when `from` is zero, `amount` tokens will be minted for `to`. * - when `from` is zero, `amount` tokens will be minted for `to`.
* - when `to` is zero, `amount` of ``from``'s tokens will be burned. * - when `to` is zero, `amount` of ``from``'s tokens will be burned.
* - `from` and `to` are never both zero. * - `from` and `to` are never both zero.
...@@ -325,4 +331,24 @@ contract ERC20 is Context, IERC20, IERC20Metadata { ...@@ -325,4 +331,24 @@ contract ERC20 is Context, IERC20, IERC20Metadata {
address to, address to,
uint256 amount uint256 amount
) internal virtual {} ) internal virtual {}
/**
* @dev Hook that is called after any transfer of tokens. This includes
* minting and burning.
*
* Calling conditions:
*
* - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
* has been transferred to `to`.
* - when `from` is zero, `amount` tokens have been minted for `to`.
* - when `to` is zero, `amount` of ``from``'s tokens have been burned.
* - `from` and `to` are never both zero.
*
* To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
*/
function _afterTokenTransfer(
address from,
address to,
uint256 amount
) internal virtual {}
} }
...@@ -190,11 +190,13 @@ abstract contract ERC20Votes is ERC20Permit { ...@@ -190,11 +190,13 @@ abstract contract ERC20Votes is ERC20Permit {
* *
* Emits a {DelegateVotesChanged} event. * Emits a {DelegateVotesChanged} event.
*/ */
function _beforeTokenTransfer( function _afterTokenTransfer(
address from, address from,
address to, address to,
uint256 amount uint256 amount
) internal virtual override { ) internal virtual override {
super._afterTokenTransfer(from, to, amount);
_moveVotingPower(delegates(from), delegates(to), amount); _moveVotingPower(delegates(from), delegates(to), amount);
} }
......
...@@ -306,6 +306,9 @@ contract('ERC20Votes', function (accounts) { ...@@ -306,6 +306,9 @@ contract('ERC20Votes', function (accounts) {
expectEvent(receipt, 'Transfer', { from: holder, to: recipient, value: '1' }); expectEvent(receipt, 'Transfer', { from: holder, to: recipient, value: '1' });
expectEvent(receipt, 'DelegateVotesChanged', { delegate: holder, previousBalance: supply, newBalance: supply.subn(1) }); expectEvent(receipt, 'DelegateVotesChanged', { delegate: holder, previousBalance: supply, newBalance: supply.subn(1) });
const { logIndex: transferLogIndex } = receipt.logs.find(({ event }) => event == 'Transfer');
expect(receipt.logs.filter(({ event }) => event == 'DelegateVotesChanged').every(({ logIndex }) => transferLogIndex < logIndex)).to.be.equal(true);
this.holderVotes = supply.subn(1); this.holderVotes = supply.subn(1);
this.recipientVotes = '0'; this.recipientVotes = '0';
}); });
...@@ -317,6 +320,9 @@ contract('ERC20Votes', function (accounts) { ...@@ -317,6 +320,9 @@ contract('ERC20Votes', function (accounts) {
expectEvent(receipt, 'Transfer', { from: holder, to: recipient, value: '1' }); expectEvent(receipt, 'Transfer', { from: holder, to: recipient, value: '1' });
expectEvent(receipt, 'DelegateVotesChanged', { delegate: recipient, previousBalance: '0', newBalance: '1' }); expectEvent(receipt, 'DelegateVotesChanged', { delegate: recipient, previousBalance: '0', newBalance: '1' });
const { logIndex: transferLogIndex } = receipt.logs.find(({ event }) => event == 'Transfer');
expect(receipt.logs.filter(({ event }) => event == 'DelegateVotesChanged').every(({ logIndex }) => transferLogIndex < logIndex)).to.be.equal(true);
this.holderVotes = '0'; this.holderVotes = '0';
this.recipientVotes = '1'; this.recipientVotes = '1';
}); });
...@@ -330,6 +336,9 @@ contract('ERC20Votes', function (accounts) { ...@@ -330,6 +336,9 @@ contract('ERC20Votes', function (accounts) {
expectEvent(receipt, 'DelegateVotesChanged', { delegate: holder, previousBalance: supply, newBalance: supply.subn(1) }); expectEvent(receipt, 'DelegateVotesChanged', { delegate: holder, previousBalance: supply, newBalance: supply.subn(1) });
expectEvent(receipt, 'DelegateVotesChanged', { delegate: recipient, previousBalance: '0', newBalance: '1' }); expectEvent(receipt, 'DelegateVotesChanged', { delegate: recipient, previousBalance: '0', newBalance: '1' });
const { logIndex: transferLogIndex } = receipt.logs.find(({ event }) => event == 'Transfer');
expect(receipt.logs.filter(({ event }) => event == 'DelegateVotesChanged').every(({ logIndex }) => transferLogIndex < logIndex)).to.be.equal(true);
this.holderVotes = supply.subn(1); this.holderVotes = supply.subn(1);
this.recipientVotes = '1'; this.recipientVotes = '1';
}); });
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment