ERC777Upgradeable.sol 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581
  1. // SPDX-License-Identifier: MIT
  2. // OpenZeppelin Contracts (last updated v4.5.0) (token/ERC777/ERC777.sol)
  3. pragma solidity ^0.8.0;
  4. import "./IERC777Upgradeable.sol";
  5. import "./IERC777RecipientUpgradeable.sol";
  6. import "./IERC777SenderUpgradeable.sol";
  7. import "../ERC20/IERC20Upgradeable.sol";
  8. import "../../utils/AddressUpgradeable.sol";
  9. import "../../utils/ContextUpgradeable.sol";
  10. import "../../utils/introspection/IERC1820RegistryUpgradeable.sol";
  11. import "../../proxy/utils/Initializable.sol";
  12. /**
  13. * @dev Implementation of the {IERC777} interface.
  14. *
  15. * This implementation is agnostic to the way tokens are created. This means
  16. * that a supply mechanism has to be added in a derived contract using {_mint}.
  17. *
  18. * Support for ERC20 is included in this contract, as specified by the EIP: both
  19. * the ERC777 and ERC20 interfaces can be safely used when interacting with it.
  20. * Both {IERC777-Sent} and {IERC20-Transfer} events are emitted on token
  21. * movements.
  22. *
  23. * Additionally, the {IERC777-granularity} value is hard-coded to `1`, meaning that there
  24. * are no special restrictions in the amount of tokens that created, moved, or
  25. * destroyed. This makes integration with ERC20 applications seamless.
  26. */
  27. contract ERC777Upgradeable is Initializable, ContextUpgradeable, IERC777Upgradeable, IERC20Upgradeable {
  28. using AddressUpgradeable for address;
  29. IERC1820RegistryUpgradeable internal constant _ERC1820_REGISTRY = IERC1820RegistryUpgradeable(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);
  30. mapping(address => uint256) private _balances;
  31. uint256 private _totalSupply;
  32. string private _name;
  33. string private _symbol;
  34. bytes32 private constant _TOKENS_SENDER_INTERFACE_HASH = keccak256("ERC777TokensSender");
  35. bytes32 private constant _TOKENS_RECIPIENT_INTERFACE_HASH = keccak256("ERC777TokensRecipient");
  36. // This isn't ever read from - it's only used to respond to the defaultOperators query.
  37. address[] private _defaultOperatorsArray;
  38. // Immutable, but accounts may revoke them (tracked in __revokedDefaultOperators).
  39. mapping(address => bool) private _defaultOperators;
  40. // For each account, a mapping of its operators and revoked default operators.
  41. mapping(address => mapping(address => bool)) private _operators;
  42. mapping(address => mapping(address => bool)) private _revokedDefaultOperators;
  43. // ERC20-allowances
  44. mapping(address => mapping(address => uint256)) private _allowances;
  45. /**
  46. * @dev `defaultOperators` may be an empty array.
  47. */
  48. function __ERC777_init(
  49. string memory name_,
  50. string memory symbol_,
  51. address[] memory defaultOperators_
  52. ) internal onlyInitializing {
  53. __ERC777_init_unchained(name_, symbol_, defaultOperators_);
  54. }
  55. function __ERC777_init_unchained(
  56. string memory name_,
  57. string memory symbol_,
  58. address[] memory defaultOperators_
  59. ) internal onlyInitializing {
  60. _name = name_;
  61. _symbol = symbol_;
  62. _defaultOperatorsArray = defaultOperators_;
  63. for (uint256 i = 0; i < defaultOperators_.length; i++) {
  64. _defaultOperators[defaultOperators_[i]] = true;
  65. }
  66. // register interfaces
  67. _ERC1820_REGISTRY.setInterfaceImplementer(address(this), keccak256("ERC777Token"), address(this));
  68. _ERC1820_REGISTRY.setInterfaceImplementer(address(this), keccak256("ERC20Token"), address(this));
  69. }
  70. /**
  71. * @dev See {IERC777-name}.
  72. */
  73. function name() public view virtual override returns (string memory) {
  74. return _name;
  75. }
  76. /**
  77. * @dev See {IERC777-symbol}.
  78. */
  79. function symbol() public view virtual override returns (string memory) {
  80. return _symbol;
  81. }
  82. /**
  83. * @dev See {ERC20-decimals}.
  84. *
  85. * Always returns 18, as per the
  86. * [ERC777 EIP](https://eips.ethereum.org/EIPS/eip-777#backward-compatibility).
  87. */
  88. function decimals() public pure virtual returns (uint8) {
  89. return 18;
  90. }
  91. /**
  92. * @dev See {IERC777-granularity}.
  93. *
  94. * This implementation always returns `1`.
  95. */
  96. function granularity() public view virtual override returns (uint256) {
  97. return 1;
  98. }
  99. /**
  100. * @dev See {IERC777-totalSupply}.
  101. */
  102. function totalSupply() public view virtual override(IERC20Upgradeable, IERC777Upgradeable) returns (uint256) {
  103. return _totalSupply;
  104. }
  105. /**
  106. * @dev Returns the amount of tokens owned by an account (`tokenHolder`).
  107. */
  108. function balanceOf(address tokenHolder) public view virtual override(IERC20Upgradeable, IERC777Upgradeable) returns (uint256) {
  109. return _balances[tokenHolder];
  110. }
  111. /**
  112. * @dev See {IERC777-send}.
  113. *
  114. * Also emits a {IERC20-Transfer} event for ERC20 compatibility.
  115. */
  116. function send(
  117. address recipient,
  118. uint256 amount,
  119. bytes memory data
  120. ) public virtual override {
  121. _send(_msgSender(), recipient, amount, data, "", true);
  122. }
  123. /**
  124. * @dev See {IERC20-transfer}.
  125. *
  126. * Unlike `send`, `recipient` is _not_ required to implement the {IERC777Recipient}
  127. * interface if it is a contract.
  128. *
  129. * Also emits a {Sent} event.
  130. */
  131. function transfer(address recipient, uint256 amount) public virtual override returns (bool) {
  132. require(recipient != address(0), "ERC777: transfer to the zero address");
  133. address from = _msgSender();
  134. _callTokensToSend(from, from, recipient, amount, "", "");
  135. _move(from, from, recipient, amount, "", "");
  136. _callTokensReceived(from, from, recipient, amount, "", "", false);
  137. return true;
  138. }
  139. /**
  140. * @dev See {IERC777-burn}.
  141. *
  142. * Also emits a {IERC20-Transfer} event for ERC20 compatibility.
  143. */
  144. function burn(uint256 amount, bytes memory data) public virtual override {
  145. _burn(_msgSender(), amount, data, "");
  146. }
  147. /**
  148. * @dev See {IERC777-isOperatorFor}.
  149. */
  150. function isOperatorFor(address operator, address tokenHolder) public view virtual override returns (bool) {
  151. return
  152. operator == tokenHolder ||
  153. (_defaultOperators[operator] && !_revokedDefaultOperators[tokenHolder][operator]) ||
  154. _operators[tokenHolder][operator];
  155. }
  156. /**
  157. * @dev See {IERC777-authorizeOperator}.
  158. */
  159. function authorizeOperator(address operator) public virtual override {
  160. require(_msgSender() != operator, "ERC777: authorizing self as operator");
  161. if (_defaultOperators[operator]) {
  162. delete _revokedDefaultOperators[_msgSender()][operator];
  163. } else {
  164. _operators[_msgSender()][operator] = true;
  165. }
  166. emit AuthorizedOperator(operator, _msgSender());
  167. }
  168. /**
  169. * @dev See {IERC777-revokeOperator}.
  170. */
  171. function revokeOperator(address operator) public virtual override {
  172. require(operator != _msgSender(), "ERC777: revoking self as operator");
  173. if (_defaultOperators[operator]) {
  174. _revokedDefaultOperators[_msgSender()][operator] = true;
  175. } else {
  176. delete _operators[_msgSender()][operator];
  177. }
  178. emit RevokedOperator(operator, _msgSender());
  179. }
  180. /**
  181. * @dev See {IERC777-defaultOperators}.
  182. */
  183. function defaultOperators() public view virtual override returns (address[] memory) {
  184. return _defaultOperatorsArray;
  185. }
  186. /**
  187. * @dev See {IERC777-operatorSend}.
  188. *
  189. * Emits {Sent} and {IERC20-Transfer} events.
  190. */
  191. function operatorSend(
  192. address sender,
  193. address recipient,
  194. uint256 amount,
  195. bytes memory data,
  196. bytes memory operatorData
  197. ) public virtual override {
  198. require(isOperatorFor(_msgSender(), sender), "ERC777: caller is not an operator for holder");
  199. _send(sender, recipient, amount, data, operatorData, true);
  200. }
  201. /**
  202. * @dev See {IERC777-operatorBurn}.
  203. *
  204. * Emits {Burned} and {IERC20-Transfer} events.
  205. */
  206. function operatorBurn(
  207. address account,
  208. uint256 amount,
  209. bytes memory data,
  210. bytes memory operatorData
  211. ) public virtual override {
  212. require(isOperatorFor(_msgSender(), account), "ERC777: caller is not an operator for holder");
  213. _burn(account, amount, data, operatorData);
  214. }
  215. /**
  216. * @dev See {IERC20-allowance}.
  217. *
  218. * Note that operator and allowance concepts are orthogonal: operators may
  219. * not have allowance, and accounts with allowance may not be operators
  220. * themselves.
  221. */
  222. function allowance(address holder, address spender) public view virtual override returns (uint256) {
  223. return _allowances[holder][spender];
  224. }
  225. /**
  226. * @dev See {IERC20-approve}.
  227. *
  228. * NOTE: If `value` is the maximum `uint256`, the allowance is not updated on
  229. * `transferFrom`. This is semantically equivalent to an infinite approval.
  230. *
  231. * Note that accounts cannot have allowance issued by their operators.
  232. */
  233. function approve(address spender, uint256 value) public virtual override returns (bool) {
  234. address holder = _msgSender();
  235. _approve(holder, spender, value);
  236. return true;
  237. }
  238. /**
  239. * @dev See {IERC20-transferFrom}.
  240. *
  241. * NOTE: Does not update the allowance if the current allowance
  242. * is the maximum `uint256`.
  243. *
  244. * Note that operator and allowance concepts are orthogonal: operators cannot
  245. * call `transferFrom` (unless they have allowance), and accounts with
  246. * allowance cannot call `operatorSend` (unless they are operators).
  247. *
  248. * Emits {Sent}, {IERC20-Transfer} and {IERC20-Approval} events.
  249. */
  250. function transferFrom(
  251. address holder,
  252. address recipient,
  253. uint256 amount
  254. ) public virtual override returns (bool) {
  255. require(recipient != address(0), "ERC777: transfer to the zero address");
  256. require(holder != address(0), "ERC777: transfer from the zero address");
  257. address spender = _msgSender();
  258. _callTokensToSend(spender, holder, recipient, amount, "", "");
  259. _spendAllowance(holder, spender, amount);
  260. _move(spender, holder, recipient, amount, "", "");
  261. _callTokensReceived(spender, holder, recipient, amount, "", "", false);
  262. return true;
  263. }
  264. /**
  265. * @dev Creates `amount` tokens and assigns them to `account`, increasing
  266. * the total supply.
  267. *
  268. * If a send hook is registered for `account`, the corresponding function
  269. * will be called with `operator`, `data` and `operatorData`.
  270. *
  271. * See {IERC777Sender} and {IERC777Recipient}.
  272. *
  273. * Emits {Minted} and {IERC20-Transfer} events.
  274. *
  275. * Requirements
  276. *
  277. * - `account` cannot be the zero address.
  278. * - if `account` is a contract, it must implement the {IERC777Recipient}
  279. * interface.
  280. */
  281. function _mint(
  282. address account,
  283. uint256 amount,
  284. bytes memory userData,
  285. bytes memory operatorData
  286. ) internal virtual {
  287. _mint(account, amount, userData, operatorData, true);
  288. }
  289. /**
  290. * @dev Creates `amount` tokens and assigns them to `account`, increasing
  291. * the total supply.
  292. *
  293. * If `requireReceptionAck` is set to true, and if a send hook is
  294. * registered for `account`, the corresponding function will be called with
  295. * `operator`, `data` and `operatorData`.
  296. *
  297. * See {IERC777Sender} and {IERC777Recipient}.
  298. *
  299. * Emits {Minted} and {IERC20-Transfer} events.
  300. *
  301. * Requirements
  302. *
  303. * - `account` cannot be the zero address.
  304. * - if `account` is a contract, it must implement the {IERC777Recipient}
  305. * interface.
  306. */
  307. function _mint(
  308. address account,
  309. uint256 amount,
  310. bytes memory userData,
  311. bytes memory operatorData,
  312. bool requireReceptionAck
  313. ) internal virtual {
  314. require(account != address(0), "ERC777: mint to the zero address");
  315. address operator = _msgSender();
  316. _beforeTokenTransfer(operator, address(0), account, amount);
  317. // Update state variables
  318. _totalSupply += amount;
  319. _balances[account] += amount;
  320. _callTokensReceived(operator, address(0), account, amount, userData, operatorData, requireReceptionAck);
  321. emit Minted(operator, account, amount, userData, operatorData);
  322. emit Transfer(address(0), account, amount);
  323. }
  324. /**
  325. * @dev Send tokens
  326. * @param from address token holder address
  327. * @param to address recipient address
  328. * @param amount uint256 amount of tokens to transfer
  329. * @param userData bytes extra information provided by the token holder (if any)
  330. * @param operatorData bytes extra information provided by the operator (if any)
  331. * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient
  332. */
  333. function _send(
  334. address from,
  335. address to,
  336. uint256 amount,
  337. bytes memory userData,
  338. bytes memory operatorData,
  339. bool requireReceptionAck
  340. ) internal virtual {
  341. require(from != address(0), "ERC777: send from the zero address");
  342. require(to != address(0), "ERC777: send to the zero address");
  343. address operator = _msgSender();
  344. _callTokensToSend(operator, from, to, amount, userData, operatorData);
  345. _move(operator, from, to, amount, userData, operatorData);
  346. _callTokensReceived(operator, from, to, amount, userData, operatorData, requireReceptionAck);
  347. }
  348. /**
  349. * @dev Burn tokens
  350. * @param from address token holder address
  351. * @param amount uint256 amount of tokens to burn
  352. * @param data bytes extra information provided by the token holder
  353. * @param operatorData bytes extra information provided by the operator (if any)
  354. */
  355. function _burn(
  356. address from,
  357. uint256 amount,
  358. bytes memory data,
  359. bytes memory operatorData
  360. ) internal virtual {
  361. require(from != address(0), "ERC777: burn from the zero address");
  362. address operator = _msgSender();
  363. _callTokensToSend(operator, from, address(0), amount, data, operatorData);
  364. _beforeTokenTransfer(operator, from, address(0), amount);
  365. // Update state variables
  366. uint256 fromBalance = _balances[from];
  367. require(fromBalance >= amount, "ERC777: burn amount exceeds balance");
  368. unchecked {
  369. _balances[from] = fromBalance - amount;
  370. }
  371. _totalSupply -= amount;
  372. emit Burned(operator, from, amount, data, operatorData);
  373. emit Transfer(from, address(0), amount);
  374. }
  375. function _move(
  376. address operator,
  377. address from,
  378. address to,
  379. uint256 amount,
  380. bytes memory userData,
  381. bytes memory operatorData
  382. ) private {
  383. _beforeTokenTransfer(operator, from, to, amount);
  384. uint256 fromBalance = _balances[from];
  385. require(fromBalance >= amount, "ERC777: transfer amount exceeds balance");
  386. unchecked {
  387. _balances[from] = fromBalance - amount;
  388. }
  389. _balances[to] += amount;
  390. emit Sent(operator, from, to, amount, userData, operatorData);
  391. emit Transfer(from, to, amount);
  392. }
  393. /**
  394. * @dev See {ERC20-_approve}.
  395. *
  396. * Note that accounts cannot have allowance issued by their operators.
  397. */
  398. function _approve(
  399. address holder,
  400. address spender,
  401. uint256 value
  402. ) internal virtual {
  403. require(holder != address(0), "ERC777: approve from the zero address");
  404. require(spender != address(0), "ERC777: approve to the zero address");
  405. _allowances[holder][spender] = value;
  406. emit Approval(holder, spender, value);
  407. }
  408. /**
  409. * @dev Call from.tokensToSend() if the interface is registered
  410. * @param operator address operator requesting the transfer
  411. * @param from address token holder address
  412. * @param to address recipient address
  413. * @param amount uint256 amount of tokens to transfer
  414. * @param userData bytes extra information provided by the token holder (if any)
  415. * @param operatorData bytes extra information provided by the operator (if any)
  416. */
  417. function _callTokensToSend(
  418. address operator,
  419. address from,
  420. address to,
  421. uint256 amount,
  422. bytes memory userData,
  423. bytes memory operatorData
  424. ) private {
  425. address implementer = _ERC1820_REGISTRY.getInterfaceImplementer(from, _TOKENS_SENDER_INTERFACE_HASH);
  426. if (implementer != address(0)) {
  427. IERC777SenderUpgradeable(implementer).tokensToSend(operator, from, to, amount, userData, operatorData);
  428. }
  429. }
  430. /**
  431. * @dev Call to.tokensReceived() if the interface is registered. Reverts if the recipient is a contract but
  432. * tokensReceived() was not registered for the recipient
  433. * @param operator address operator requesting the transfer
  434. * @param from address token holder address
  435. * @param to address recipient address
  436. * @param amount uint256 amount of tokens to transfer
  437. * @param userData bytes extra information provided by the token holder (if any)
  438. * @param operatorData bytes extra information provided by the operator (if any)
  439. * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient
  440. */
  441. function _callTokensReceived(
  442. address operator,
  443. address from,
  444. address to,
  445. uint256 amount,
  446. bytes memory userData,
  447. bytes memory operatorData,
  448. bool requireReceptionAck
  449. ) private {
  450. address implementer = _ERC1820_REGISTRY.getInterfaceImplementer(to, _TOKENS_RECIPIENT_INTERFACE_HASH);
  451. if (implementer != address(0)) {
  452. IERC777RecipientUpgradeable(implementer).tokensReceived(operator, from, to, amount, userData, operatorData);
  453. } else if (requireReceptionAck) {
  454. require(!to.isContract(), "ERC777: token recipient contract has no implementer for ERC777TokensRecipient");
  455. }
  456. }
  457. /**
  458. * @dev Spend `amount` form the allowance of `owner` toward `spender`.
  459. *
  460. * Does not update the allowance amount in case of infinite allowance.
  461. * Revert if not enough allowance is available.
  462. *
  463. * Might emit an {Approval} event.
  464. */
  465. function _spendAllowance(
  466. address owner,
  467. address spender,
  468. uint256 amount
  469. ) internal virtual {
  470. uint256 currentAllowance = allowance(owner, spender);
  471. if (currentAllowance != type(uint256).max) {
  472. require(currentAllowance >= amount, "ERC777: insufficient allowance");
  473. unchecked {
  474. _approve(owner, spender, currentAllowance - amount);
  475. }
  476. }
  477. }
  478. /**
  479. * @dev Hook that is called before any token transfer. This includes
  480. * calls to {send}, {transfer}, {operatorSend}, minting and burning.
  481. *
  482. * Calling conditions:
  483. *
  484. * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
  485. * will be to transferred to `to`.
  486. * - when `from` is zero, `amount` tokens will be minted for `to`.
  487. * - when `to` is zero, `amount` of ``from``'s tokens will be burned.
  488. * - `from` and `to` are never both zero.
  489. *
  490. * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
  491. */
  492. function _beforeTokenTransfer(
  493. address operator,
  494. address from,
  495. address to,
  496. uint256 amount
  497. ) internal virtual {}
  498. /**
  499. * This empty reserved space is put in place to allow future versions to add new
  500. * variables without shifting down storage in the inheritance chain.
  501. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
  502. */
  503. uint256[41] private __gap;
  504. }