applyHarness.patch 44 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100
  1. diff -ruN access/AccessControl.sol access/AccessControl.sol
  2. --- access/AccessControl.sol 2022-09-20 11:01:10.429515094 +0200
  3. +++ access/AccessControl.sol 2022-09-20 14:34:08.629602185 +0200
  4. @@ -93,7 +93,7 @@
  5. *
  6. * _Available since v4.6._
  7. */
  8. - function _checkRole(bytes32 role) internal view virtual {
  9. + function _checkRole(bytes32 role) public view virtual { // HARNESS: internal -> public
  10. _checkRole(role, _msgSender());
  11. }
  12. diff -ruN access/Ownable.sol access/Ownable.sol
  13. --- access/Ownable.sol 2022-09-09 10:15:55.887175731 +0200
  14. +++ access/Ownable.sol 2022-09-20 14:34:08.629602185 +0200
  15. @@ -30,14 +30,6 @@
  16. }
  17. /**
  18. - * @dev Throws if called by any account other than the owner.
  19. - */
  20. - modifier onlyOwner() {
  21. - _checkOwner();
  22. - _;
  23. - }
  24. -
  25. - /**
  26. * @dev Returns the address of the current owner.
  27. */
  28. function owner() public view virtual returns (address) {
  29. @@ -45,10 +37,11 @@
  30. }
  31. /**
  32. - * @dev Throws if the sender is not the owner.
  33. + * @dev Throws if called by any account other than the owner.
  34. */
  35. - function _checkOwner() internal view virtual {
  36. + modifier onlyOwner() {
  37. require(owner() == _msgSender(), "Ownable: caller is not the owner");
  38. + _;
  39. }
  40. /**
  41. diff -ruN .gitignore .gitignore
  42. --- .gitignore 1970-01-01 01:00:00.000000000 +0100
  43. +++ .gitignore 2022-09-20 14:34:08.626268788 +0200
  44. @@ -0,0 +1,2 @@
  45. +*
  46. +!.gitignore
  47. diff -ruN governance/extensions/GovernorCountingSimple.sol governance/extensions/GovernorCountingSimple.sol
  48. --- governance/extensions/GovernorCountingSimple.sol 2022-09-20 11:01:10.432848512 +0200
  49. +++ governance/extensions/GovernorCountingSimple.sol 2022-09-20 14:34:08.632935582 +0200
  50. @@ -27,7 +27,7 @@
  51. mapping(address => bool) hasVoted;
  52. }
  53. - mapping(uint256 => ProposalVote) private _proposalVotes;
  54. + mapping(uint256 => ProposalVote) internal _proposalVotes;
  55. /**
  56. * @dev See {IGovernor-COUNTING_MODE}.
  57. diff -ruN governance/extensions/GovernorPreventLateQuorum.sol governance/extensions/GovernorPreventLateQuorum.sol
  58. --- governance/extensions/GovernorPreventLateQuorum.sol 2022-08-31 13:44:36.377724869 +0200
  59. +++ governance/extensions/GovernorPreventLateQuorum.sol 2022-09-20 14:34:08.632935582 +0200
  60. @@ -21,8 +21,8 @@
  61. using SafeCast for uint256;
  62. using Timers for Timers.BlockNumber;
  63. - uint64 private _voteExtension;
  64. - mapping(uint256 => Timers.BlockNumber) private _extendedDeadlines;
  65. + uint64 internal _voteExtension; // PRIVATE => INTERNAL
  66. + mapping(uint256 => Timers.BlockNumber) internal _extendedDeadlines; // PRIVATE => INTERNAL
  67. /// @dev Emitted when a proposal deadline is pushed back due to reaching quorum late in its voting period.
  68. event ProposalExtended(uint256 indexed proposalId, uint64 extendedDeadline);
  69. diff -ruN governance/Governor.sol governance/Governor.sol
  70. --- governance/Governor.sol 2022-09-20 11:01:10.429515094 +0200
  71. +++ governance/Governor.sol 2022-09-20 14:34:08.629602185 +0200
  72. @@ -44,7 +44,7 @@
  73. string private _name;
  74. - mapping(uint256 => ProposalCore) private _proposals;
  75. + mapping(uint256 => ProposalCore) internal _proposals;
  76. // This queue keeps track of the governor operating on itself. Calls to functions protected by the
  77. // {onlyGovernance} modifier needs to be whitelisted in this queue. Whitelisting is set in {_beforeExecute},
  78. diff -ruN governance/TimelockController.sol governance/TimelockController.sol
  79. --- governance/TimelockController.sol 2022-09-09 10:15:55.887175731 +0200
  80. +++ governance/TimelockController.sol 2022-09-20 14:34:08.629602185 +0200
  81. @@ -28,10 +28,10 @@
  82. bytes32 public constant PROPOSER_ROLE = keccak256("PROPOSER_ROLE");
  83. bytes32 public constant EXECUTOR_ROLE = keccak256("EXECUTOR_ROLE");
  84. bytes32 public constant CANCELLER_ROLE = keccak256("CANCELLER_ROLE");
  85. - uint256 internal constant _DONE_TIMESTAMP = uint256(1);
  86. + uint256 public constant _DONE_TIMESTAMP = uint256(1);
  87. mapping(bytes32 => uint256) private _timestamps;
  88. - uint256 private _minDelay;
  89. + uint256 public _minDelay;
  90. /**
  91. * @dev Emitted when a call is scheduled as part of operation `id`.
  92. diff -ruN governance/utils/Votes.sol governance/utils/Votes.sol
  93. --- governance/utils/Votes.sol 2022-09-20 14:24:58.010074267 +0200
  94. +++ governance/utils/Votes.sol 2022-09-20 14:34:08.632935582 +0200
  95. @@ -35,7 +35,25 @@
  96. bytes32 private constant _DELEGATION_TYPEHASH =
  97. keccak256("Delegation(address delegatee,uint256 nonce,uint256 expiry)");
  98. - mapping(address => address) private _delegation;
  99. + // HARNESS : Hooks cannot access any information from Checkpoints yet, so I am also updating votes and fromBlock in this struct
  100. + struct Ckpt {
  101. + uint32 fromBlock;
  102. + uint224 votes;
  103. + }
  104. + mapping(address => Ckpt) public _checkpoints;
  105. +
  106. + // HARNESSED getters
  107. + function numCheckpoints(address account) public view returns (uint32) {
  108. + return SafeCast.toUint32(_delegateCheckpoints[account]._checkpoints.length);
  109. + }
  110. + function ckptFromBlock(address account, uint32 pos) public view returns (uint32) {
  111. + return _delegateCheckpoints[account]._checkpoints[pos]._blockNumber;
  112. + }
  113. + function ckptVotes(address account, uint32 pos) public view returns (uint224) {
  114. + return _delegateCheckpoints[account]._checkpoints[pos]._value;
  115. + }
  116. +
  117. + mapping(address => address) public _delegation;
  118. mapping(address => Checkpoints.History) private _delegateCheckpoints;
  119. Checkpoints.History private _totalCheckpoints;
  120. @@ -124,7 +142,7 @@
  121. *
  122. * Emits events {DelegateChanged} and {DelegateVotesChanged}.
  123. */
  124. - function _delegate(address account, address delegatee) internal virtual {
  125. + function _delegate(address account, address delegatee) public virtual {
  126. address oldDelegate = delegates(account);
  127. _delegation[account] = delegatee;
  128. @@ -142,10 +160,10 @@
  129. uint256 amount
  130. ) internal virtual {
  131. if (from == address(0)) {
  132. - _totalCheckpoints.push(_add, amount);
  133. + _totalCheckpoints.push(_totalCheckpoints.latest() + amount); // Harnessed to remove function pointers
  134. }
  135. if (to == address(0)) {
  136. - _totalCheckpoints.push(_subtract, amount);
  137. + _totalCheckpoints.push(_totalCheckpoints.latest() - amount); // Harnessed to remove function pointers
  138. }
  139. _moveDelegateVotes(delegates(from), delegates(to), amount);
  140. }
  141. @@ -160,11 +178,13 @@
  142. ) private {
  143. if (from != to && amount > 0) {
  144. if (from != address(0)) {
  145. - (uint256 oldValue, uint256 newValue) = _delegateCheckpoints[from].push(_subtract, amount);
  146. + (uint256 oldValue, uint256 newValue) = _delegateCheckpoints[from].push(_delegateCheckpoints[from].latest() - amount); // HARNESSED TO REMOVE FUNCTION POINTERS
  147. + _checkpoints[from] = Ckpt({fromBlock: SafeCast.toUint32(block.number), votes: SafeCast.toUint224(newValue)}); // HARNESS
  148. emit DelegateVotesChanged(from, oldValue, newValue);
  149. }
  150. if (to != address(0)) {
  151. - (uint256 oldValue, uint256 newValue) = _delegateCheckpoints[to].push(_add, amount);
  152. + (uint256 oldValue, uint256 newValue) = _delegateCheckpoints[to].push(_delegateCheckpoints[to].latest() + amount); // HARNESSED TO REMOVE FUNCTION POINTERS
  153. + _checkpoints[to] = Ckpt({fromBlock: SafeCast.toUint32(block.number), votes: SafeCast.toUint224(newValue)}); // HARNESS
  154. emit DelegateVotesChanged(to, oldValue, newValue);
  155. }
  156. }
  157. @@ -207,5 +227,5 @@
  158. /**
  159. * @dev Must return the voting units held by an account.
  160. */
  161. - function _getVotingUnits(address) internal view virtual returns (uint256);
  162. + function _getVotingUnits(address) public virtual returns (uint256); // HARNESS: internal -> public
  163. }
  164. diff -ruN metatx/MinimalForwarder.sol metatx/MinimalForwarder.sol
  165. --- metatx/MinimalForwarder.sol 2022-09-20 11:16:48.456850883 +0200
  166. +++ metatx/MinimalForwarder.sol 2022-09-20 14:34:08.632935582 +0200
  167. @@ -8,11 +8,6 @@
  168. /**
  169. * @dev Simple minimal forwarder to be used together with an ERC2771 compatible contract. See {ERC2771Context}.
  170. - *
  171. - * MinimalForwarder is mainly meant for testing, as it is missing features to be a good production-ready forwarder. This
  172. - * contract does not intend to have all the properties that are needed for a sound forwarding system. A fully
  173. - * functioning forwarding system with good properties requires more complexity. We suggest you look at other projects
  174. - * such as the GSN which do have the goal of building a system like that.
  175. */
  176. contract MinimalForwarder is EIP712 {
  177. using ECDSA for bytes32;
  178. diff -ruN mocks/ERC20TokenizedVaultMock.sol mocks/ERC20TokenizedVaultMock.sol
  179. --- mocks/ERC20TokenizedVaultMock.sol 1970-01-01 01:00:00.000000000 +0100
  180. +++ mocks/ERC20TokenizedVaultMock.sol 2022-09-20 14:34:08.632935582 +0200
  181. @@ -0,0 +1,22 @@
  182. +// SPDX-License-Identifier: MIT
  183. +
  184. +pragma solidity ^0.8.0;
  185. +
  186. +import "../token/ERC20/extensions/ERC20TokenizedVault.sol";
  187. +
  188. +// mock class using ERC20
  189. +contract ERC20TokenizedVaultMock is ERC20TokenizedVault {
  190. + constructor(
  191. + IERC20Metadata asset,
  192. + string memory name,
  193. + string memory symbol
  194. + ) ERC20(name, symbol) ERC20TokenizedVault(asset) {}
  195. +
  196. + function mockMint(address account, uint256 amount) public {
  197. + _mint(account, amount);
  198. + }
  199. +
  200. + function mockBurn(address account, uint256 amount) public {
  201. + _burn(account, amount);
  202. + }
  203. +}
  204. diff -ruN mocks/MathMock.sol mocks/MathMock.sol
  205. --- mocks/MathMock.sol 2022-09-20 14:24:58.013407601 +0200
  206. +++ mocks/MathMock.sol 2022-09-20 14:34:24.803248911 +0200
  207. @@ -45,4 +45,8 @@
  208. function log256(uint256 a, Math.Rounding direction) public pure returns (uint256) {
  209. return Math.log256(a, direction);
  210. }
  211. +
  212. + function sqrt(uint256 a, Math.Rounding direction) public pure returns (uint256) {
  213. + return Math.sqrt(a, direction);
  214. + }
  215. }
  216. diff -ruN mocks/SafeERC20Helper.sol mocks/SafeERC20Helper.sol
  217. --- mocks/SafeERC20Helper.sol 2022-09-20 14:24:58.013407601 +0200
  218. +++ mocks/SafeERC20Helper.sol 2022-09-20 15:09:17.135329080 +0200
  219. @@ -4,7 +4,6 @@
  220. import "../utils/Context.sol";
  221. import "../token/ERC20/IERC20.sol";
  222. -import "../token/ERC20/extensions/draft-ERC20Permit.sol";
  223. import "../token/ERC20/utils/SafeERC20.sol";
  224. contract ERC20ReturnFalseMock is Context {
  225. @@ -106,42 +105,43 @@
  226. }
  227. }
  228. -contract ERC20PermitNoRevertMock is
  229. - ERC20("ERC20PermitNoRevertMock", "ERC20PermitNoRevertMock"),
  230. - ERC20Permit("ERC20PermitNoRevertMock")
  231. -{
  232. - function getChainId() external view returns (uint256) {
  233. - return block.chainid;
  234. - }
  235. -
  236. - function permitThatMayRevert(
  237. - address owner,
  238. - address spender,
  239. - uint256 value,
  240. - uint256 deadline,
  241. - uint8 v,
  242. - bytes32 r,
  243. - bytes32 s
  244. - ) public {
  245. - super.permit(owner, spender, value, deadline, v, r, s);
  246. - }
  247. -
  248. - function permit(
  249. - address owner,
  250. - address spender,
  251. - uint256 value,
  252. - uint256 deadline,
  253. - uint8 v,
  254. - bytes32 r,
  255. - bytes32 s
  256. - ) public override {
  257. - try this.permitThatMayRevert(owner, spender, value, deadline, v, r, s) {
  258. - // do nothing
  259. - } catch {
  260. - // do nothing
  261. - }
  262. - }
  263. -}
  264. +// Harness remove ?
  265. +// contract ERC20PermitNoRevertMock is
  266. +// ERC20("ERC20PermitNoRevertMock", "ERC20PermitNoRevertMock"),
  267. +// ERC20Permit("ERC20PermitNoRevertMock")
  268. +// {
  269. +// function getChainId() external view returns (uint256) {
  270. +// return block.chainid;
  271. +// }
  272. +
  273. +// function permitThatMayRevert(
  274. +// address owner,
  275. +// address spender,
  276. +// uint256 value,
  277. +// uint256 deadline,
  278. +// uint8 v,
  279. +// bytes32 r,
  280. +// bytes32 s
  281. +// ) public {
  282. +// super.permit(owner, spender, value, deadline, v, r, s);
  283. +// }
  284. +
  285. +// function permit(
  286. +// address owner,
  287. +// address spender,
  288. +// uint256 value,
  289. +// uint256 deadline,
  290. +// uint8 v,
  291. +// bytes32 r,
  292. +// bytes32 s
  293. +// ) public override {
  294. +// try this.permitThatMayRevert(owner, spender, value, deadline, v, r, s) {
  295. +// // do nothing
  296. +// } catch {
  297. +// // do nothing
  298. +// }
  299. +// }
  300. +// }
  301. contract SafeERC20Wrapper is Context {
  302. using SafeERC20 for IERC20;
  303. @@ -172,18 +172,6 @@
  304. _token.safeDecreaseAllowance(address(0), amount);
  305. }
  306. - function permit(
  307. - address owner,
  308. - address spender,
  309. - uint256 value,
  310. - uint256 deadline,
  311. - uint8 v,
  312. - bytes32 r,
  313. - bytes32 s
  314. - ) public {
  315. - SafeERC20.safePermit(IERC20Permit(address(_token)), owner, spender, value, deadline, v, r, s);
  316. - }
  317. -
  318. function setAllowance(uint256 allowance_) public {
  319. ERC20ReturnTrueMock(address(_token)).setAllowance(allowance_);
  320. }
  321. diff -ruN proxy/beacon/BeaconProxy.sol proxy/beacon/BeaconProxy.sol
  322. --- proxy/beacon/BeaconProxy.sol 2022-09-09 10:15:55.890509851 +0200
  323. +++ proxy/beacon/BeaconProxy.sol 2022-09-20 14:34:24.806582310 +0200
  324. @@ -28,6 +28,7 @@
  325. * - `beacon` must be a contract with the interface {IBeacon}.
  326. */
  327. constructor(address beacon, bytes memory data) payable {
  328. + assert(_BEACON_SLOT == bytes32(uint256(keccak256("eip1967.proxy.beacon")) - 1));
  329. _upgradeBeaconToAndCall(beacon, data, false);
  330. }
  331. diff -ruN proxy/Clones.sol proxy/Clones.sol
  332. --- proxy/Clones.sol 2022-09-20 14:24:58.013407601 +0200
  333. +++ proxy/Clones.sol 2022-09-20 14:59:00.690035663 +0200
  334. @@ -27,10 +27,10 @@
  335. assembly {
  336. // Cleans the upper 96 bits of the `implementation` word, then packs the first 3 bytes
  337. // of the `implementation` address with the bytecode before the address.
  338. - mstore(0x00, or(shr(0xe8, shl(0x60, implementation)), 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000))
  339. + mstore(0x00, or(shr(0xe8, shl(0x60, implementation)), 0x602d8060093d393df3363d3d373d3d3d363d73000000))
  340. // Packs the remaining 17 bytes of `implementation` with the bytecode after the address.
  341. mstore(0x20, or(shl(0x78, implementation), 0x5af43d82803e903d91602b57fd5bf3))
  342. - instance := create(0, 0x09, 0x37)
  343. + instance := create(0, 0x0A, 0x36)
  344. }
  345. require(instance != address(0), "ERC1167: create failed");
  346. }
  347. @@ -47,10 +47,10 @@
  348. assembly {
  349. // Cleans the upper 96 bits of the `implementation` word, then packs the first 3 bytes
  350. // of the `implementation` address with the bytecode before the address.
  351. - mstore(0x00, or(shr(0xe8, shl(0x60, implementation)), 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000))
  352. + mstore(0x00, or(shr(0xe8, shl(0x60, implementation)), 0x602d8060093d393df3363d3d373d3d3d363d73000000))
  353. // Packs the remaining 17 bytes of `implementation` with the bytecode after the address.
  354. mstore(0x20, or(shl(0x78, implementation), 0x5af43d82803e903d91602b57fd5bf3))
  355. - instance := create2(0, 0x09, 0x37, salt)
  356. + instance := create2(0, 0x0A, 0x36, salt)
  357. }
  358. require(instance != address(0), "ERC1167: create2 failed");
  359. }
  360. @@ -66,13 +66,13 @@
  361. /// @solidity memory-safe-assembly
  362. assembly {
  363. let ptr := mload(0x40)
  364. - mstore(add(ptr, 0x38), deployer)
  365. - mstore(add(ptr, 0x24), 0x5af43d82803e903d91602b57fd5bf3ff)
  366. - mstore(add(ptr, 0x14), implementation)
  367. - mstore(ptr, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73)
  368. - mstore(add(ptr, 0x58), salt)
  369. - mstore(add(ptr, 0x78), keccak256(add(ptr, 0x0c), 0x37))
  370. - predicted := keccak256(add(ptr, 0x43), 0x55)
  371. + mstore(add(ptr, 0x37), deployer)
  372. + mstore(add(ptr, 0x23), 0x5af43d82803e903d91602b57fd5bf3ff)
  373. + mstore(add(ptr, 0x13), implementation)
  374. + mstore(ptr, 0x602d8060093d393df3363d3d373d3d3d363d73)
  375. + mstore(add(ptr, 0x57), salt)
  376. + mstore(add(ptr, 0x77), keccak256(add(ptr, 0x0b), 0x36))
  377. + predicted := keccak256(add(ptr, 0x44), 0x55)
  378. }
  379. }
  380. diff -ruN proxy/ERC1967/ERC1967Proxy.sol proxy/ERC1967/ERC1967Proxy.sol
  381. --- proxy/ERC1967/ERC1967Proxy.sol 2022-09-09 10:15:55.890509851 +0200
  382. +++ proxy/ERC1967/ERC1967Proxy.sol 2022-09-20 14:34:24.806582310 +0200
  383. @@ -20,6 +20,7 @@
  384. * function call, and allows initializing the storage of the proxy like a Solidity constructor.
  385. */
  386. constructor(address _logic, bytes memory _data) payable {
  387. + assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256("eip1967.proxy.implementation")) - 1));
  388. _upgradeToAndCall(_logic, _data, false);
  389. }
  390. diff -ruN proxy/transparent/TransparentUpgradeableProxy.sol proxy/transparent/TransparentUpgradeableProxy.sol
  391. --- proxy/transparent/TransparentUpgradeableProxy.sol 2022-09-09 10:15:55.890509851 +0200
  392. +++ proxy/transparent/TransparentUpgradeableProxy.sol 2022-09-20 14:34:24.806582310 +0200
  393. @@ -36,6 +36,7 @@
  394. address admin_,
  395. bytes memory _data
  396. ) payable ERC1967Proxy(_logic, _data) {
  397. + assert(_ADMIN_SLOT == bytes32(uint256(keccak256("eip1967.proxy.admin")) - 1));
  398. _changeAdmin(admin_);
  399. }
  400. diff -ruN proxy/utils/Initializable.sol proxy/utils/Initializable.sol
  401. --- proxy/utils/Initializable.sol 2022-09-20 11:16:48.456850883 +0200
  402. +++ proxy/utils/Initializable.sol 2022-09-20 14:34:24.806582310 +0200
  403. @@ -59,12 +59,12 @@
  404. * @dev Indicates that the contract has been initialized.
  405. * @custom:oz-retyped-from bool
  406. */
  407. - uint8 private _initialized;
  408. + uint8 internal _initialized;
  409. /**
  410. * @dev Indicates that the contract is in the process of being initialized.
  411. */
  412. - bool private _initializing;
  413. + bool internal _initializing;
  414. /**
  415. * @dev Triggered when the contract has been initialized or reinitialized.
  416. diff -ruN security/Pausable.sol security/Pausable.sol
  417. --- security/Pausable.sol 2022-09-09 10:15:55.890509851 +0200
  418. +++ security/Pausable.sol 2022-09-20 14:34:24.809915708 +0200
  419. @@ -35,6 +35,13 @@
  420. }
  421. /**
  422. + * @dev Returns true if the contract is paused, and false otherwise.
  423. + */
  424. + function paused() public view virtual returns (bool) {
  425. + return _paused;
  426. + }
  427. +
  428. + /**
  429. * @dev Modifier to make a function callable only when the contract is not paused.
  430. *
  431. * Requirements:
  432. @@ -42,7 +49,7 @@
  433. * - The contract must not be paused.
  434. */
  435. modifier whenNotPaused() {
  436. - _requireNotPaused();
  437. + require(!paused(), "Pausable: paused");
  438. _;
  439. }
  440. @@ -54,29 +61,8 @@
  441. * - The contract must be paused.
  442. */
  443. modifier whenPaused() {
  444. - _requirePaused();
  445. - _;
  446. - }
  447. -
  448. - /**
  449. - * @dev Returns true if the contract is paused, and false otherwise.
  450. - */
  451. - function paused() public view virtual returns (bool) {
  452. - return _paused;
  453. - }
  454. -
  455. - /**
  456. - * @dev Throws if the contract is paused.
  457. - */
  458. - function _requireNotPaused() internal view virtual {
  459. - require(!paused(), "Pausable: paused");
  460. - }
  461. -
  462. - /**
  463. - * @dev Throws if the contract is not paused.
  464. - */
  465. - function _requirePaused() internal view virtual {
  466. require(paused(), "Pausable: not paused");
  467. + _;
  468. }
  469. /**
  470. diff -ruN token/ERC1155/ERC1155.sol token/ERC1155/ERC1155.sol
  471. --- token/ERC1155/ERC1155.sol 2022-09-20 11:01:10.432848512 +0200
  472. +++ token/ERC1155/ERC1155.sol 2022-09-20 14:34:24.809915708 +0200
  473. @@ -21,7 +21,7 @@
  474. using Address for address;
  475. // Mapping from token ID to account balances
  476. - mapping(uint256 => mapping(address => uint256)) private _balances;
  477. + mapping(uint256 => mapping(address => uint256)) internal _balances; // MUNGED private => internal
  478. // Mapping from account to operator approvals
  479. mapping(address => mapping(address => bool)) private _operatorApprovals;
  480. @@ -471,7 +471,7 @@
  481. uint256 id,
  482. uint256 amount,
  483. bytes memory data
  484. - ) private {
  485. + ) public { // HARNESS: private -> public
  486. if (to.isContract()) {
  487. try IERC1155Receiver(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {
  488. if (response != IERC1155Receiver.onERC1155Received.selector) {
  489. @@ -492,7 +492,7 @@
  490. uint256[] memory ids,
  491. uint256[] memory amounts,
  492. bytes memory data
  493. - ) private {
  494. + ) public { // HARNESS: private -> public
  495. if (to.isContract()) {
  496. try IERC1155Receiver(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (
  497. bytes4 response
  498. diff -ruN token/ERC20/ERC20.sol token/ERC20/ERC20.sol
  499. --- token/ERC20/ERC20.sol 2022-09-20 13:34:47.024598756 +0200
  500. +++ token/ERC20/ERC20.sol 2022-09-20 14:34:24.809915708 +0200
  501. @@ -282,7 +282,7 @@
  502. * - `account` cannot be the zero address.
  503. * - `account` must have at least `amount` tokens.
  504. */
  505. - function _burn(address account, uint256 amount) internal virtual {
  506. + function _burn(address account, uint256 amount) public virtual { // HARNESS: internal -> public
  507. require(account != address(0), "ERC20: burn from the zero address");
  508. _beforeTokenTransfer(account, address(0), amount);
  509. diff -ruN token/ERC20/extensions/ERC20FlashMint.sol token/ERC20/extensions/ERC20FlashMint.sol
  510. --- token/ERC20/extensions/ERC20FlashMint.sol 2022-09-20 11:01:10.432848512 +0200
  511. +++ token/ERC20/extensions/ERC20FlashMint.sol 2022-09-20 14:34:24.809915708 +0200
  512. @@ -51,9 +51,11 @@
  513. // silence warning about unused variable without the addition of bytecode.
  514. token;
  515. amount;
  516. - return 0;
  517. + return fee; // HARNESS: made "return" nonzero
  518. }
  519. + uint256 public fee; // HARNESS: added it to simulate random fee amount
  520. +
  521. /**
  522. * @dev Returns the receiver address of the flash fee. By default this
  523. * implementation returns the address(0) which means the fee amount will be burnt.
  524. diff -ruN token/ERC20/extensions/ERC20TokenizedVault.sol token/ERC20/extensions/ERC20TokenizedVault.sol
  525. --- token/ERC20/extensions/ERC20TokenizedVault.sol 1970-01-01 01:00:00.000000000 +0100
  526. +++ token/ERC20/extensions/ERC20TokenizedVault.sol 2022-09-20 14:34:24.809915708 +0200
  527. @@ -0,0 +1,217 @@
  528. +// SPDX-License-Identifier: MIT
  529. +
  530. +pragma solidity ^0.8.0;
  531. +
  532. +import "../ERC20.sol";
  533. +import "../utils/SafeERC20.sol";
  534. +import "../../../interfaces/IERC4626.sol";
  535. +import "../../../utils/math/Math.sol";
  536. +
  537. +/**
  538. + * @dev Implementation of the ERC4626 "Tokenized Vault Standard" as defined in
  539. + * https://eips.ethereum.org/EIPS/eip-4626[EIP-4626].
  540. + *
  541. + * This extension allows the minting and burning of "shares" (represented using the ERC20 inheritance) in exchange for
  542. + * underlying "assets" through standardized {deposit}, {mint}, {redeem} and {burn} workflows. This contract extends
  543. + * the ERC20 standard. Any additional extensions included along it would affect the "shares" token represented by this
  544. + * contract and not the "assets" token which is an independent contract.
  545. + *
  546. + * _Available since v4.7._
  547. + */
  548. +abstract contract ERC20TokenizedVault is ERC20, IERC4626 {
  549. + using Math for uint256;
  550. +
  551. + IERC20Metadata private immutable _asset;
  552. +
  553. + /**
  554. + * @dev Set the underlying asset contract. This must be an ERC20-compatible contract (ERC20 or ERC777).
  555. + */
  556. + constructor(IERC20Metadata asset_) {
  557. + _asset = asset_;
  558. + }
  559. +
  560. + /** @dev See {IERC4262-asset} */
  561. + function asset() public view virtual override returns (address) {
  562. + return address(_asset);
  563. + }
  564. +
  565. + /** @dev See {IERC4262-totalAssets} */
  566. + function totalAssets() public view virtual override returns (uint256) {
  567. + return _asset.balanceOf(address(this));
  568. + }
  569. +
  570. + /** @dev See {IERC4262-convertToShares} */
  571. + function convertToShares(uint256 assets) public view virtual override returns (uint256 shares) {
  572. + return _convertToShares(assets, Math.Rounding.Down);
  573. + }
  574. +
  575. + /** @dev See {IERC4262-convertToAssets} */
  576. + function convertToAssets(uint256 shares) public view virtual override returns (uint256 assets) {
  577. + return _convertToAssets(shares, Math.Rounding.Down);
  578. + }
  579. +
  580. + /** @dev See {IERC4262-maxDeposit} */
  581. + function maxDeposit(address) public view virtual override returns (uint256) {
  582. + return _isVaultCollateralized() ? type(uint256).max : 0;
  583. + }
  584. +
  585. + /** @dev See {IERC4262-maxMint} */
  586. + function maxMint(address) public view virtual override returns (uint256) {
  587. + return type(uint256).max;
  588. + }
  589. +
  590. + /** @dev See {IERC4262-maxWithdraw} */
  591. + function maxWithdraw(address owner) public view virtual override returns (uint256) {
  592. + return _convertToAssets(balanceOf(owner), Math.Rounding.Down);
  593. + }
  594. +
  595. + /** @dev See {IERC4262-maxRedeem} */
  596. + function maxRedeem(address owner) public view virtual override returns (uint256) {
  597. + return balanceOf(owner);
  598. + }
  599. +
  600. + /** @dev See {IERC4262-previewDeposit} */
  601. + function previewDeposit(uint256 assets) public view virtual override returns (uint256) {
  602. + return _convertToShares(assets, Math.Rounding.Down);
  603. + }
  604. +
  605. + /** @dev See {IERC4262-previewMint} */
  606. + function previewMint(uint256 shares) public view virtual override returns (uint256) {
  607. + return _convertToAssets(shares, Math.Rounding.Up);
  608. + }
  609. +
  610. + /** @dev See {IERC4262-previewWithdraw} */
  611. + function previewWithdraw(uint256 assets) public view virtual override returns (uint256) {
  612. + return _convertToShares(assets, Math.Rounding.Up);
  613. + }
  614. +
  615. + /** @dev See {IERC4262-previewRedeem} */
  616. + function previewRedeem(uint256 shares) public view virtual override returns (uint256) {
  617. + return _convertToAssets(shares, Math.Rounding.Down);
  618. + }
  619. +
  620. + /** @dev See {IERC4262-deposit} */
  621. + function deposit(uint256 assets, address receiver) public virtual override returns (uint256) {
  622. + require(assets <= maxDeposit(receiver), "ERC20TokenizedVault: deposit more than max");
  623. +
  624. + uint256 shares = previewDeposit(assets);
  625. + _deposit(_msgSender(), receiver, assets, shares);
  626. +
  627. + return shares;
  628. + }
  629. +
  630. + /** @dev See {IERC4262-mint} */
  631. + function mint(uint256 shares, address receiver) public virtual override returns (uint256) {
  632. + require(shares <= maxMint(receiver), "ERC20TokenizedVault: mint more than max");
  633. +
  634. + uint256 assets = previewMint(shares);
  635. + _deposit(_msgSender(), receiver, assets, shares);
  636. +
  637. + return assets;
  638. + }
  639. +
  640. + /** @dev See {IERC4262-withdraw} */
  641. + function withdraw(
  642. + uint256 assets,
  643. + address receiver,
  644. + address owner
  645. + ) public virtual override returns (uint256) {
  646. + require(assets <= maxWithdraw(owner), "ERC20TokenizedVault: withdraw more than max");
  647. +
  648. + uint256 shares = previewWithdraw(assets);
  649. + _withdraw(_msgSender(), receiver, owner, assets, shares);
  650. +
  651. + return shares;
  652. + }
  653. +
  654. + /** @dev See {IERC4262-redeem} */
  655. + function redeem(
  656. + uint256 shares,
  657. + address receiver,
  658. + address owner
  659. + ) public virtual override returns (uint256) {
  660. + require(shares <= maxRedeem(owner), "ERC20TokenizedVault: redeem more than max");
  661. +
  662. + uint256 assets = previewRedeem(shares);
  663. + _withdraw(_msgSender(), receiver, owner, assets, shares);
  664. +
  665. + return assets;
  666. + }
  667. +
  668. + /**
  669. + * @dev Internal convertion function (from assets to shares) with support for rounding direction
  670. + *
  671. + * Will revert if assets > 0, totalSupply > 0 and totalAssets = 0. That corresponds to a case where any asset
  672. + * would represent an infinite amout of shares.
  673. + */
  674. + function _convertToShares(uint256 assets, Math.Rounding rounding) internal view virtual returns (uint256 shares) {
  675. + uint256 supply = totalSupply();
  676. + return
  677. + (assets == 0 || supply == 0)
  678. + ? assets.mulDiv(10**decimals(), 10**_asset.decimals(), rounding)
  679. + : assets.mulDiv(supply, totalAssets(), rounding);
  680. + }
  681. +
  682. + /**
  683. + * @dev Internal convertion function (from shares to assets) with support for rounding direction
  684. + */
  685. + function _convertToAssets(uint256 shares, Math.Rounding rounding) internal view virtual returns (uint256 assets) {
  686. + uint256 supply = totalSupply();
  687. + return
  688. + (supply == 0)
  689. + ? shares.mulDiv(10**_asset.decimals(), 10**decimals(), rounding)
  690. + : shares.mulDiv(totalAssets(), supply, rounding);
  691. + }
  692. +
  693. + /**
  694. + * @dev Deposit/mint common workflow
  695. + */
  696. + function _deposit(
  697. + address caller,
  698. + address receiver,
  699. + uint256 assets,
  700. + uint256 shares
  701. + ) private {
  702. + // If _asset is ERC777, `transferFrom` can trigger a reenterancy BEFORE the transfer happens through the
  703. + // `tokensToSend` hook. On the other hand, the `tokenReceived` hook, that is triggered after the transfer,
  704. + // calls the vault, which is assumed not malicious.
  705. + //
  706. + // Conclusion: we need to do the transfer before we mint so that any reentrancy would happen before the
  707. + // assets are transfered and before the shares are minted, which is a valid state.
  708. + // slither-disable-next-line reentrancy-no-eth
  709. + SafeERC20.safeTransferFrom(_asset, caller, address(this), assets);
  710. + _mint(receiver, shares);
  711. +
  712. + emit Deposit(caller, receiver, assets, shares);
  713. + }
  714. +
  715. + /**
  716. + * @dev Withdraw/redeem common workflow
  717. + */
  718. + function _withdraw(
  719. + address caller,
  720. + address receiver,
  721. + address owner,
  722. + uint256 assets,
  723. + uint256 shares
  724. + ) private {
  725. + if (caller != owner) {
  726. + _spendAllowance(owner, caller, shares);
  727. + }
  728. +
  729. + // If _asset is ERC777, `transfer` can trigger trigger a reentrancy AFTER the transfer happens through the
  730. + // `tokensReceived` hook. On the other hand, the `tokensToSend` hook, that is triggered before the transfer,
  731. + // calls the vault, which is assumed not malicious.
  732. + //
  733. + // Conclusion: we need to do the transfer after the burn so that any reentrancy would happen after the
  734. + // shares are burned and after the assets are transfered, which is a valid state.
  735. + _burn(owner, shares);
  736. + SafeERC20.safeTransfer(_asset, receiver, assets);
  737. +
  738. + emit Withdraw(caller, receiver, owner, assets, shares);
  739. + }
  740. +
  741. + function _isVaultCollateralized() private view returns (bool) {
  742. + return totalAssets() > 0 || totalSupply() == 0;
  743. + }
  744. +}
  745. diff -ruN token/ERC20/extensions/ERC20Votes.sol token/ERC20/extensions/ERC20Votes.sol
  746. --- token/ERC20/extensions/ERC20Votes.sol 2022-09-20 14:24:58.016740934 +0200
  747. +++ token/ERC20/extensions/ERC20Votes.sol 2022-09-20 15:05:11.770836991 +0200
  748. @@ -33,8 +33,8 @@
  749. bytes32 private constant _DELEGATION_TYPEHASH =
  750. keccak256("Delegation(address delegatee,uint256 nonce,uint256 expiry)");
  751. - mapping(address => address) private _delegates;
  752. - mapping(address => Checkpoint[]) private _checkpoints;
  753. + mapping(address => address) public _delegates;
  754. + mapping(address => Checkpoint[]) public _checkpoints;
  755. Checkpoint[] private _totalSupplyCheckpoints;
  756. /**
  757. @@ -165,7 +165,7 @@
  758. /**
  759. * @dev Maximum token supply. Defaults to `type(uint224).max` (2^224^ - 1).
  760. */
  761. - function _maxSupply() internal view virtual returns (uint224) {
  762. + function _maxSupply() public view virtual returns (uint224) { //harnessed to public
  763. return type(uint224).max;
  764. }
  765. @@ -176,16 +176,16 @@
  766. super._mint(account, amount);
  767. require(totalSupply() <= _maxSupply(), "ERC20Votes: total supply risks overflowing votes");
  768. - _writeCheckpoint(_totalSupplyCheckpoints, _add, amount);
  769. + _writeCheckpointAdd(_totalSupplyCheckpoints, amount); // HARNESS: new version without pointer
  770. }
  771. /**
  772. * @dev Snapshots the totalSupply after it has been decreased.
  773. */
  774. - function _burn(address account, uint256 amount) internal virtual override {
  775. + function _burn(address account, uint256 amount) public virtual override { // HARNESS: internal -> public (to comply with the ERC20 harness)
  776. super._burn(account, amount);
  777. - _writeCheckpoint(_totalSupplyCheckpoints, _subtract, amount);
  778. + _writeCheckpointSub(_totalSupplyCheckpoints, amount); // HARNESS: new version without pointer
  779. }
  780. /**
  781. @@ -208,7 +208,7 @@
  782. *
  783. * Emits events {DelegateChanged} and {DelegateVotesChanged}.
  784. */
  785. - function _delegate(address delegator, address delegatee) internal virtual {
  786. + function _delegate(address delegator, address delegatee) public virtual { // HARNESSED TO MAKE PUBLIC
  787. address currentDelegate = delegates(delegator);
  788. uint256 delegatorBalance = balanceOf(delegator);
  789. _delegates[delegator] = delegatee;
  790. @@ -225,12 +225,13 @@
  791. ) private {
  792. if (src != dst && amount > 0) {
  793. if (src != address(0)) {
  794. - (uint256 oldWeight, uint256 newWeight) = _writeCheckpoint(_checkpoints[src], _subtract, amount);
  795. + (uint256 oldWeight, uint256 newWeight) = _writeCheckpointSub(_checkpoints[src], amount); // HARNESS: new version without pointer
  796. +
  797. emit DelegateVotesChanged(src, oldWeight, newWeight);
  798. }
  799. if (dst != address(0)) {
  800. - (uint256 oldWeight, uint256 newWeight) = _writeCheckpoint(_checkpoints[dst], _add, amount);
  801. + (uint256 oldWeight, uint256 newWeight) = _writeCheckpointAdd(_checkpoints[dst], amount); // HARNESS: new version without pointer
  802. emit DelegateVotesChanged(dst, oldWeight, newWeight);
  803. }
  804. }
  805. @@ -255,6 +256,55 @@
  806. }
  807. }
  808. + // HARNESS: split _writeCheckpoint() to two functions as a workaround for function pointers that cannot be managed by the tool
  809. + function _writeCheckpointAdd(
  810. + Checkpoint[] storage ckpts,
  811. + uint256 delta
  812. + ) private returns (uint256 oldWeight, uint256 newWeight) {
  813. + uint256 pos = ckpts.length;
  814. + oldWeight = pos == 0 ? 0 : ckpts[pos - 1].votes;
  815. + newWeight = _add(oldWeight, delta);
  816. +
  817. + if (pos > 0 && ckpts[pos - 1].fromBlock == block.number) {
  818. + ckpts[pos - 1].votes = SafeCast.toUint224(newWeight);
  819. + } else {
  820. + ckpts.push(Checkpoint({fromBlock: SafeCast.toUint32(block.number), votes: SafeCast.toUint224(newWeight)}));
  821. + }
  822. + }
  823. +
  824. + function _writeCheckpointSub(
  825. + Checkpoint[] storage ckpts,
  826. + uint256 delta
  827. + ) private returns (uint256 oldWeight, uint256 newWeight) {
  828. + uint256 pos = ckpts.length;
  829. + oldWeight = pos == 0 ? 0 : ckpts[pos - 1].votes;
  830. + newWeight = _subtract(oldWeight, delta);
  831. +
  832. + if (pos > 0 && ckpts[pos - 1].fromBlock == block.number) {
  833. + ckpts[pos - 1].votes = SafeCast.toUint224(newWeight);
  834. + } else {
  835. + ckpts.push(Checkpoint({fromBlock: SafeCast.toUint32(block.number), votes: SafeCast.toUint224(newWeight)}));
  836. + }
  837. + }
  838. +
  839. + // backup of original function
  840. + //
  841. + // function _writeCheckpoint(
  842. + // Checkpoint[] storage ckpts,
  843. + // function(uint256, uint256) view returns (uint256) op,
  844. + // uint256 delta
  845. + // ) private returns (uint256 oldWeight, uint256 newWeight) {
  846. + // uint256 pos = ckpts.length;
  847. + // oldWeight = pos == 0 ? 0 : ckpts[pos - 1].votes;
  848. + // newWeight = op(oldWeight, delta);
  849. + //
  850. + // if (pos > 0 && ckpts[pos - 1].fromBlock == block.number) {
  851. + // ckpts[pos - 1].votes = SafeCast.toUint224(newWeight);
  852. + // } else {
  853. + // ckpts.push(Checkpoint({fromBlock: SafeCast.toUint32(block.number), votes: SafeCast.toUint224(newWeight)}));
  854. + // }
  855. + // }
  856. +
  857. function _add(uint256 a, uint256 b) private pure returns (uint256) {
  858. return a + b;
  859. }
  860. diff -ruN token/ERC20/extensions/ERC20Wrapper.sol token/ERC20/extensions/ERC20Wrapper.sol
  861. --- token/ERC20/extensions/ERC20Wrapper.sol 2022-08-31 13:44:36.381058287 +0200
  862. +++ token/ERC20/extensions/ERC20Wrapper.sol 2022-09-20 14:34:24.809915708 +0200
  863. @@ -1,5 +1,5 @@
  864. // SPDX-License-Identifier: MIT
  865. -// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/extensions/ERC20Wrapper.sol)
  866. +// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/ERC20Wrapper.sol)
  867. pragma solidity ^0.8.0;
  868. @@ -23,17 +23,6 @@
  869. }
  870. /**
  871. - * @dev See {ERC20-decimals}.
  872. - */
  873. - function decimals() public view virtual override returns (uint8) {
  874. - try IERC20Metadata(address(underlying)).decimals() returns (uint8 value) {
  875. - return value;
  876. - } catch {
  877. - return super.decimals();
  878. - }
  879. - }
  880. -
  881. - /**
  882. * @dev Allow a user to deposit underlying tokens and mint the corresponding number of wrapped tokens.
  883. */
  884. function depositFor(address account, uint256 amount) public virtual returns (bool) {
  885. @@ -55,7 +44,7 @@
  886. * @dev Mint wrapped token to cover any underlyingTokens that would have been transferred by mistake. Internal
  887. * function that can be exposed with access control if desired.
  888. */
  889. - function _recover(address account) internal virtual returns (uint256) {
  890. + function _recover(address account) public virtual returns (uint256) { // HARNESS: internal -> public
  891. uint256 value = underlying.balanceOf(address(this)) - totalSupply();
  892. _mint(account, value);
  893. return value;
  894. diff -ruN token/ERC20/README.adoc token/ERC20/README.adoc
  895. --- token/ERC20/README.adoc 2022-09-20 13:34:47.024598756 +0200
  896. +++ token/ERC20/README.adoc 2022-09-20 14:34:24.809915708 +0200
  897. @@ -24,7 +24,7 @@
  898. * {ERC20Votes}: support for voting and vote delegation.
  899. * {ERC20VotesComp}: support for voting and vote delegation (compatible with Compound's token, with uint96 restrictions).
  900. * {ERC20Wrapper}: wrapper to create an ERC20 backed by another ERC20, with deposit and withdraw methods. Useful in conjunction with {ERC20Votes}.
  901. -* {ERC4626}: tokenized vault that manages shares (represented as ERC20) that are backed by assets (another ERC20).
  902. +* {ERC20TokenizedVault}: tokenized vault that manages shares (represented as ERC20) that are backed by assets (another ERC20).
  903. Finally, there are some utilities to interact with ERC20 contracts in various ways.
  904. @@ -63,7 +63,7 @@
  905. {{ERC20FlashMint}}
  906. -{{ERC4626}}
  907. +{{ERC20TokenizedVault}}
  908. == Draft EIPs
  909. diff -ruN token/ERC20/utils/SafeERC20.sol token/ERC20/utils/SafeERC20.sol
  910. --- token/ERC20/utils/SafeERC20.sol 2022-09-09 10:15:55.893843970 +0200
  911. +++ token/ERC20/utils/SafeERC20.sol 2022-09-20 14:34:28.259983206 +0200
  912. @@ -4,7 +4,6 @@
  913. pragma solidity ^0.8.0;
  914. import "../IERC20.sol";
  915. -import "../extensions/draft-IERC20Permit.sol";
  916. import "../../../utils/Address.sol";
  917. /**
  918. @@ -80,22 +79,6 @@
  919. }
  920. }
  921. - function safePermit(
  922. - IERC20Permit token,
  923. - address owner,
  924. - address spender,
  925. - uint256 value,
  926. - uint256 deadline,
  927. - uint8 v,
  928. - bytes32 r,
  929. - bytes32 s
  930. - ) internal {
  931. - uint256 nonceBefore = token.nonces(owner);
  932. - token.permit(owner, spender, value, deadline, v, r, s);
  933. - uint256 nonceAfter = token.nonces(owner);
  934. - require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed");
  935. - }
  936. -
  937. /**
  938. * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
  939. * on the return value: the return value is optional (but if data is returned, it must not be false).
  940. diff -ruN token/ERC721/extensions/draft-ERC721Votes.sol token/ERC721/extensions/draft-ERC721Votes.sol
  941. --- token/ERC721/extensions/draft-ERC721Votes.sol 2022-09-20 14:24:58.016740934 +0200
  942. +++ token/ERC721/extensions/draft-ERC721Votes.sol 2022-09-20 14:34:28.259983206 +0200
  943. @@ -49,7 +49,7 @@
  944. /**
  945. * @dev Returns the balance of `account`.
  946. */
  947. - function _getVotingUnits(address account) internal view virtual override returns (uint256) {
  948. + function _getVotingUnits(address account) public view virtual override returns (uint256) {
  949. return balanceOf(account);
  950. }
  951. }
  952. diff -ruN utils/Address.sol utils/Address.sol
  953. --- utils/Address.sol 2022-09-20 11:01:10.432848512 +0200
  954. +++ utils/Address.sol 2022-09-20 14:34:28.259983206 +0200
  955. @@ -131,6 +131,7 @@
  956. uint256 value,
  957. string memory errorMessage
  958. ) internal returns (bytes memory) {
  959. + return ""; // external calls havoc
  960. require(address(this).balance >= value, "Address: insufficient balance for call");
  961. (bool success, bytes memory returndata) = target.call{value: value}(data);
  962. return verifyCallResultFromTarget(target, success, returndata, errorMessage);
  963. diff -ruN utils/math/Math.sol utils/math/Math.sol
  964. --- utils/math/Math.sol 2022-09-20 14:24:58.016740934 +0200
  965. +++ utils/math/Math.sol 2022-09-20 14:34:29.036665098 +0200
  966. @@ -342,4 +342,78 @@
  967. return result + (rounding == Rounding.Up && 1 << (result * 8) < value ? 1 : 0);
  968. }
  969. }
  970. +
  971. + /**
  972. + * @dev Returns the square root of a number. It the number is not a perfect square, the value is rounded down.
  973. + *
  974. + * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11).
  975. + */
  976. + function sqrt(uint256 a) internal pure returns (uint256) {
  977. + if (a == 0) {
  978. + return 0;
  979. + }
  980. +
  981. + // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.
  982. + // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have
  983. + // `msb(a) <= a < 2*msb(a)`.
  984. + // We also know that `k`, the position of the most significant bit, is such that `msb(a) = 2**k`.
  985. + // This gives `2**k < a <= 2**(k+1)` → `2**(k/2) <= sqrt(a) < 2 ** (k/2+1)`.
  986. + // Using an algorithm similar to the msb conmputation, we are able to compute `result = 2**(k/2)` which is a
  987. + // good first aproximation of `sqrt(a)` with at least 1 correct bit.
  988. + uint256 result = 1;
  989. + uint256 x = a;
  990. + if (x >> 128 > 0) {
  991. + x >>= 128;
  992. + result <<= 64;
  993. + }
  994. + if (x >> 64 > 0) {
  995. + x >>= 64;
  996. + result <<= 32;
  997. + }
  998. + if (x >> 32 > 0) {
  999. + x >>= 32;
  1000. + result <<= 16;
  1001. + }
  1002. + if (x >> 16 > 0) {
  1003. + x >>= 16;
  1004. + result <<= 8;
  1005. + }
  1006. + if (x >> 8 > 0) {
  1007. + x >>= 8;
  1008. + result <<= 4;
  1009. + }
  1010. + if (x >> 4 > 0) {
  1011. + x >>= 4;
  1012. + result <<= 2;
  1013. + }
  1014. + if (x >> 2 > 0) {
  1015. + result <<= 1;
  1016. + }
  1017. +
  1018. + // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,
  1019. + // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at
  1020. + // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision
  1021. + // into the expected uint128 result.
  1022. + unchecked {
  1023. + result = (result + a / result) >> 1;
  1024. + result = (result + a / result) >> 1;
  1025. + result = (result + a / result) >> 1;
  1026. + result = (result + a / result) >> 1;
  1027. + result = (result + a / result) >> 1;
  1028. + result = (result + a / result) >> 1;
  1029. + result = (result + a / result) >> 1;
  1030. + return min(result, a / result);
  1031. + }
  1032. + }
  1033. +
  1034. + /**
  1035. + * @notice Calculates sqrt(a), following the selected rounding direction.
  1036. + */
  1037. + function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {
  1038. + uint256 result = sqrt(a);
  1039. + if (rounding == Rounding.Up && result * result < a) {
  1040. + result += 1;
  1041. + }
  1042. + return result;
  1043. + }
  1044. }