Mint ERC777 without reception ack (#2552)
This commit is contained in:
@ -21,6 +21,7 @@
|
||||
* `AccessControl`: Added ERC165 interface detection. ([#2562](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2562))
|
||||
* `AccessControlEnumerable`: Fixed `renounceRole` not updated underlying set. ([#2572](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2572))
|
||||
* `ERC1155`: Make `uri` public so overloading function can call it using super. ([#2576](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2576))
|
||||
* `ERC777`: Make reception acquirement optional in `_mint`. ([#2552](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2552))
|
||||
|
||||
### How to upgrade from 3.x
|
||||
|
||||
|
||||
@ -27,6 +27,16 @@ contract ERC777Mock is Context, ERC777 {
|
||||
_mint(to, amount, userData, operatorData);
|
||||
}
|
||||
|
||||
function mintInternalExtended (
|
||||
address to,
|
||||
uint256 amount,
|
||||
bytes memory userData,
|
||||
bytes memory operatorData,
|
||||
bool requireReceptionAck
|
||||
) public {
|
||||
_mint(to, amount, userData, operatorData, requireReceptionAck);
|
||||
}
|
||||
|
||||
function approveInternal(address holder, address spender, uint256 value) public {
|
||||
_approve(holder, spender, value);
|
||||
}
|
||||
|
||||
@ -312,6 +312,37 @@ contract ERC777 is Context, IERC777, IERC20 {
|
||||
)
|
||||
internal
|
||||
virtual
|
||||
{
|
||||
_mint(account, amount, userData, operatorData, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Creates `amount` tokens and assigns them to `account`, increasing
|
||||
* the total supply.
|
||||
*
|
||||
* If `requireReceptionAck` is set to true, and if a send hook is
|
||||
* registered for `account`, the corresponding function will be called with
|
||||
* `operator`, `data` and `operatorData`.
|
||||
*
|
||||
* See {IERC777Sender} and {IERC777Recipient}.
|
||||
*
|
||||
* Emits {Minted} and {IERC20-Transfer} events.
|
||||
*
|
||||
* Requirements
|
||||
*
|
||||
* - `account` cannot be the zero address.
|
||||
* - if `account` is a contract, it must implement the {IERC777Recipient}
|
||||
* interface.
|
||||
*/
|
||||
function _mint(
|
||||
address account,
|
||||
uint256 amount,
|
||||
bytes memory userData,
|
||||
bytes memory operatorData,
|
||||
bool requireReceptionAck
|
||||
)
|
||||
internal
|
||||
virtual
|
||||
{
|
||||
require(account != address(0), "ERC777: mint to the zero address");
|
||||
|
||||
@ -323,7 +354,7 @@ contract ERC777 is Context, IERC777, IERC20 {
|
||||
_totalSupply += amount;
|
||||
_balances[account] += amount;
|
||||
|
||||
_callTokensReceived(operator, address(0), account, amount, userData, operatorData, true);
|
||||
_callTokensReceived(operator, address(0), account, amount, userData, operatorData, requireReceptionAck);
|
||||
|
||||
emit Minted(operator, account, amount, userData, operatorData);
|
||||
emit Transfer(address(0), account, amount);
|
||||
|
||||
@ -171,6 +171,133 @@ contract('ERC777', function (accounts) {
|
||||
shouldBehaveLikeERC777InternalMint(to, operator, amount, data, operatorData);
|
||||
});
|
||||
});
|
||||
|
||||
describe('mint (internal extended)', function () {
|
||||
const amount = new BN('5');
|
||||
|
||||
context('to anyone', function () {
|
||||
beforeEach(async function () {
|
||||
this.recipient = anyone;
|
||||
});
|
||||
|
||||
context('with default operator', function () {
|
||||
const operator = defaultOperatorA;
|
||||
|
||||
it('without requireReceptionAck', async function () {
|
||||
await this.token.mintInternalExtended(
|
||||
this.recipient,
|
||||
amount,
|
||||
data,
|
||||
operatorData,
|
||||
false,
|
||||
{ from: operator },
|
||||
);
|
||||
});
|
||||
|
||||
it('with requireReceptionAck', async function () {
|
||||
await this.token.mintInternalExtended(
|
||||
this.recipient,
|
||||
amount,
|
||||
data,
|
||||
operatorData,
|
||||
true,
|
||||
{ from: operator },
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
context('with non operator', function () {
|
||||
const operator = newOperator;
|
||||
|
||||
it('without requireReceptionAck', async function () {
|
||||
await this.token.mintInternalExtended(
|
||||
this.recipient,
|
||||
amount,
|
||||
data,
|
||||
operatorData,
|
||||
false,
|
||||
{ from: operator },
|
||||
);
|
||||
});
|
||||
|
||||
it('with requireReceptionAck', async function () {
|
||||
await this.token.mintInternalExtended(
|
||||
this.recipient,
|
||||
amount,
|
||||
data,
|
||||
operatorData,
|
||||
true,
|
||||
{ from: operator },
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
context('to non ERC777TokensRecipient implementer', function () {
|
||||
beforeEach(async function () {
|
||||
this.tokensRecipientImplementer = await ERC777SenderRecipientMock.new();
|
||||
this.recipient = this.tokensRecipientImplementer.address;
|
||||
});
|
||||
|
||||
context('with default operator', function () {
|
||||
const operator = defaultOperatorA;
|
||||
|
||||
it('without requireReceptionAck', async function () {
|
||||
await this.token.mintInternalExtended(
|
||||
this.recipient,
|
||||
amount,
|
||||
data,
|
||||
operatorData,
|
||||
false,
|
||||
{ from: operator },
|
||||
);
|
||||
});
|
||||
|
||||
it('with requireReceptionAck', async function () {
|
||||
await expectRevert(
|
||||
this.token.mintInternalExtended(
|
||||
this.recipient,
|
||||
amount,
|
||||
data,
|
||||
operatorData,
|
||||
true,
|
||||
{ from: operator },
|
||||
),
|
||||
'ERC777: token recipient contract has no implementer for ERC777TokensRecipient',
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
context('with non operator', function () {
|
||||
const operator = newOperator;
|
||||
|
||||
it('without requireReceptionAck', async function () {
|
||||
await this.token.mintInternalExtended(
|
||||
this.recipient,
|
||||
amount,
|
||||
data,
|
||||
operatorData,
|
||||
false,
|
||||
{ from: operator },
|
||||
);
|
||||
});
|
||||
|
||||
it('with requireReceptionAck', async function () {
|
||||
await expectRevert(
|
||||
this.token.mintInternalExtended(
|
||||
this.recipient,
|
||||
amount,
|
||||
data,
|
||||
operatorData,
|
||||
true,
|
||||
{ from: operator },
|
||||
),
|
||||
'ERC777: token recipient contract has no implementer for ERC777TokensRecipient',
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('operator management', function () {
|
||||
|
||||
Reference in New Issue
Block a user