Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Modernize codebase #296

Merged
merged 22 commits into from
May 22, 2020
Merged

Conversation

petejkim
Copy link
Contributor

@petejkim petejkim commented May 12, 2020

  1. Auto-format code using Prettier
  2. Update Truffle and Ganache to latest
  3. Fix tests that broke due to Truffle Upgrade
  4. Fix coverage tool
  5. Use ESLint for static code analysis
  6. Use latest ECMAScript syntax to clean up codebase
  7. Fix lint errors, and fix tests that were really broken but were only working accidentally (e.g. due to accidental misuse of global variable assignments and test inter-dependencies)
  8. Set up TypeScript (existing JS files aren't converted)
  9. Set up TypeScript and Solidity linters
  10. Add tests to check that storage slot positions stay the same between FiatTokenV1 and V2. This test also ensures Solidity upgrade does not affect storage slots going forward.
  11. Update smart contract from Solidity v0.4 to Solidity v0.6, making syntactical and best practices modifications where necessary
  12. Add a pre-commit hook to ensure checks are run

Note: Requires Node v12 (LTS)

@petejkim petejkim force-pushed the modernize-codebase branch 4 times, most recently from f4e5d21 to b046934 Compare May 12, 2020 21:54
- yarn install --frozen-lockfile

script:
- yarn check --integrity && truffle compile && npm test
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you mean to remove check --integrity? Is it no longer needed?

Copy link
Contributor Author

@petejkim petejkim May 14, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it's deprecated and removed from Yarn 2.x for being unreliable. It also fails when there are cross-platform differences. Since we are not bundling node_modules in this repo, it shouldn't be necessary.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, that makes sense. We were trying to stop openzeppelin-solidity and zos-lib from being modified, but it looks like the lock file is enough to handle this. I guess we never needed check-integritr.y

@petejkim petejkim marked this pull request as draft May 14, 2020 17:21
@petejkim petejkim marked this pull request as ready for review May 14, 2020 17:29
@petejkim petejkim requested a review from eztierney May 14, 2020 17:30
@@ -96,13 +96,6 @@ async function run_tests(newToken, _accounts) {
await checkVariables([token], [customVars]);
});

it("nut007 should fail to call proxy function with non-adminAccount", async () => {
Copy link
Contributor Author

@petejkim petejkim May 14, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test is removed because the ifAdmin modifier for admin() and implementation() are removed due to compilation errors. Those are marked as view functions, but if a non-admin invokes those functions, the modifier could cause a delegate call to the functions with the same name in the implementation contract that may not be read-only (i.e. not view). New versions of Solidity compiler correctly catches this and errors out. Besides there wasn't really a point since those addresses were visible regardless, and the implementation contract should never contain meaningful admin() and implementation() overrides that relies on the modifier to be callable anyway.

This test ensures slot positions are retained
post-upgrade by manually checking the use of the
slots at expected positions.
@petejkim
Copy link
Contributor Author

petejkim commented May 15, 2020

Apologies for all the force-pushes, I was amending commits as I clean up more things.

pragma solidity 0.6.8;

import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import { SafeMath } from "@openzeppelin/contracts/math/SafeMath.sol";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you have to switch openzeppelin libraries due to compiler errors? Were there any significant differences for the contracts we use from openzeppelin?

Copy link
Contributor Author

@petejkim petejkim May 18, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was to upgrade to Solidity 0.6. The previous version of OZ was using 0.4. We only use IERC20 which is just an interface and SafeMath for safe uint arithmetic, so no difference other than the language upgrade.


pragma solidity 0.6.8;

import { UpgradeabilityProxy } from "./UpgradeabilityProxy.sol";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did you copy these 3 proxy related contracts into the source tree instead of using the ones in zos-lib? At a quick glance they look very similar - were there changes you had to make?

Copy link
Contributor Author

@petejkim petejkim May 18, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I vendored those files so that I could update the syntax to Solidity 0.6.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you add a github link to the exact version this is copied from? (Also use the commit hash instead of master in the URL)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

@petejkim petejkim May 19, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in 283eca9


/**
* @title Ownable
* @dev The Ownable contract from https://github.com/zeppelinos/labs/blob/master/upgradeability_ownership/contracts/ownership/Ownable.sol
* @dev The Ownable contract from https://github.com/zeppelinos/labs/blob/master/upgradeability_ownership/contracts/ownership/Ownable.sol
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With the change on 72, this isn't a direct copy anymore. Should update this comment to reflect that. (Also the exact commit hash should be used instead of master for future proofing.)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just left the URL untouched. I can have it updated

Copy link
Contributor Author

@petejkim petejkim May 19, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in 283eca9

* @dev throws if called by any account other than the pauser
*/
modifier onlyPauser() {
require(msg.sender == pauser, "Pausable: caller is not the pauser");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this convention of prefixing the error message e.g. Pausable: is redundant, especially as tooling improves. This convention could also be tough to stay consistent with as the number of contracts grows.

Copy link
Contributor Author

@petejkim petejkim May 19, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just following the convention in OpenZeppelin repo for now. Do you suggest we remove the prefix altogether? Many other contracts, such as Uniswap V2 also follow the same convention.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think its fine to keep the prefix and match the existing conventions.

bool _newBool,
address _newAddress,
uint256 _newUint
) public {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since access permissions aren't locked down, we must ensure upgrades are only invoked through upgradeToAndCall (and not upgradeTo), to prevent an attacker from calling initV2. It may be worth locking this down with an only modifier to be safe.

Copy link
Contributor Author

@petejkim petejkim May 19, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was an existing test, didn't touch it, but I agree.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought about removing removeTo altogether, but turns out that would break a ton of existing tests, and we may want removeTo for upgrades that don't require any initialization. I think the upgrade instructions should be documented very well and be very explicit.


pragma solidity 0.6.8;

import { UpgradeabilityProxy } from "./UpgradeabilityProxy.sol";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you add a github link to the exact version this is copied from? (Also use the commit hash instead of master in the URL)

},
"repository": {
"type": "git",
"url": "git+https://github.com/centrehq/centre-tokens.git"
},
"keywords": [],
"author": "",
"license": "ISC",
"license": "MIT",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why this? They're equivalent, except that ISC removes a couple of words.

Copy link
Contributor Author

@petejkim petejkim May 19, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because the license text in the source files and the LICENSE file is MIT not ISC

const util = require("util");
const abi = require("ethereumjs-abi");
const _ = require("lodash");
const BN = require("bn.js");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see a bunch of tests were moved. Is BigNumber -> BN the only difference?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@eztierney eztierney merged commit 8aa0ddf into circlefin:master May 22, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants