Skip to content

Commit

Permalink
add solium linter + clean up contracts
Browse files Browse the repository at this point in the history
  • Loading branch information
0age committed Oct 14, 2019
1 parent e22e526 commit 185cd27
Show file tree
Hide file tree
Showing 36 changed files with 657 additions and 82 deletions.
2 changes: 1 addition & 1 deletion .solhint.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"extends": "solhint:default",
"rules": {
"indent": ["warn", 2],
"indent": "off",
"not-rely-on-time": "off",
"no-inline-assembly": "off",
"avoid-low-level-calls": "off",
Expand Down
15 changes: 15 additions & 0 deletions .soliumignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# skip
node_modules
contracts/mock/RelayContract.sol
contracts/mock/RelayContractV2.sol

# disagree with indentation error
contracts/helpers/FactoryFactFinder.sol
contracts/upgradeability/DharmaUpgradeBeaconController.sol

# parsing error due to dynamic abi.decode - try again in later version
contracts/implementations/smart-wallet/DharmaSmartWalletImplementationV0.sol
contracts/implementations/smart-wallet/DharmaSmartWalletImplementationV1.sol
contracts/implementations/smart-wallet/DharmaSmartWalletImplementationV2.sol
contracts/implementations/smart-wallet/DharmaSmartWalletImplementationV3.sol
contracts/implementations/smart-wallet/DharmaSmartWalletImplementationV4.sol
28 changes: 28 additions & 0 deletions .soliumrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"extends": "solium:all",
"plugins": [
"security"
],
"rules": {
"quotes": [
"error",
"double"
],
"indentation": [
"error",
2
],
"linebreak-style": [
"error",
"unix"
],
"lbrace": "off",
"arg-overflow": "off",
"no-experimental": "off",
"security/no-inline-assembly": "off",
"security/no-call-value": "off",
"security/no-low-level-calls": "off",
"security/no-tx-origin": "off",
"security/no-block-members": "off"
}
}
4 changes: 2 additions & 2 deletions contracts/account-recovery/DharmaAccountRecoveryManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ contract DharmaAccountRecoveryManager is Ownable, Timelocker {
* functions that already have other timelocks on them, but only if they have
* different arguments (i.e. a new wallet or user signing key is specified).
* Only the owner may call this function.
* @param functionSelector selector of the function to be called.
* @param functionSelector selector of the function to be called.
* @param arguments The abi-encoded arguments of the function to be called -
* in the case of `recover`, it is the smart wallet address and the new user
* signing key.
Expand Down Expand Up @@ -94,7 +94,7 @@ contract DharmaAccountRecoveryManager is Ownable, Timelocker {
!_accountRecoveryDisabled[wallet],
"This wallet has elected to opt out of account recovery functionality."
);

// Call the specified smart wallet and supply the new user signing key.
DharmaSmartWalletRecovery(wallet).recover(newUserSigningKey);
}
Expand Down
8 changes: 4 additions & 4 deletions contracts/factories/key-ring/DharmaKeyRingFactoryV1.sol
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ contract DharmaKeyRingFactoryV1 is DharmaKeyRingFactoryV1Interface {
bytes memory initializationCalldata = _constructInitializationCalldata(
userSigningKey
);

// Determine the user's key ring address based on the user signing key.
keyRing = _computeNextAddress(initializationCalldata);
}
Expand All @@ -202,7 +202,7 @@ contract DharmaKeyRingFactoryV1 is DharmaKeyRingFactoryV1Interface {
bytes memory initializationCalldata = _constructInitializationCalldata(
userSigningKey
);

// Deploy and initialize new user key ring as an Upgrade Beacon proxy.
keyRing = _deployUpgradeBeaconProxyInstance(initializationCalldata);

Expand Down Expand Up @@ -250,7 +250,7 @@ contract DharmaKeyRingFactoryV1 is DharmaKeyRingFactoryV1Interface {

function _constructInitializationCalldata(
address userSigningKey
) internal pure returns (bytes memory initializationCalldata) {
) private pure returns (bytes memory initializationCalldata) {
address[] memory keys = new address[](1);
keys[0] = userSigningKey;

Expand Down Expand Up @@ -299,7 +299,7 @@ contract DharmaKeyRingFactoryV1 is DharmaKeyRingFactoryV1Interface {

// Set the initial nonce to be provided when constructing the salt.
nonce = 0;

// Declare variable for code size of derived address.
uint256 codeSize;

Expand Down
12 changes: 6 additions & 6 deletions contracts/factories/smart-wallet/DharmaSmartWalletFactoryV1.sol
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import "../../../interfaces/DharmaSmartWalletInitializer.sol";
*/
contract DharmaSmartWalletFactoryV1 is DharmaSmartWalletFactoryV1Interface {
// Use Dharma Smart Wallet initializer to construct initialization calldata.
DharmaSmartWalletInitializer private _INITIALIZER;
DharmaSmartWalletInitializer private _initializer;

/**
* @notice Deploy a new smart wallet address using the provided user signing
Expand All @@ -28,10 +28,10 @@ contract DharmaSmartWalletFactoryV1 is DharmaSmartWalletFactoryV1Interface {
) external returns (address wallet) {
// Get initialization calldata from initialize selector & user signing key.
bytes memory initializationCalldata = abi.encodeWithSelector(
_INITIALIZER.initialize.selector,
_initializer.initialize.selector,
userSigningKey
);

// Initialize and deploy new user smart wallet as an Upgrade Beacon proxy.
wallet = _deployUpgradeBeaconProxyInstance(initializationCalldata);

Expand All @@ -52,10 +52,10 @@ contract DharmaSmartWalletFactoryV1 is DharmaSmartWalletFactoryV1Interface {
) external view returns (address wallet) {
// Get initialization calldata from initialize selector & user signing key.
bytes memory initializationCalldata = abi.encodeWithSelector(
_INITIALIZER.initialize.selector,
_initializer.initialize.selector,
userSigningKey
);

// Determine the user's smart wallet address based on the user signing key.
wallet = _computeNextAddress(initializationCalldata);
}
Expand Down Expand Up @@ -134,7 +134,7 @@ contract DharmaSmartWalletFactoryV1 is DharmaSmartWalletFactoryV1Interface {

// Set the initial nonce to be provided when constructing the salt.
nonce = 0;

// Declare variable for code size of derived address.
uint256 codeSize;

Expand Down
2 changes: 1 addition & 1 deletion contracts/helpers/CodeHashCache.sol
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ contract CodeHashCache {
*/
function registerCodeHash(address target) external {
// Ensure that the target contract has not already had a hash registered.
require(_cachedHashes[target] == bytes32(0), "Target already registered.");
require(_cachedHashes[target] == bytes32(0), "Target already registered.");

// Ensure that the target contract currently has runtime code.
uint256 currentCodeSize;
Expand Down
34 changes: 34 additions & 0 deletions contracts/helpers/DharmaLocksmith.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
pragma solidity 0.5.11;

import "../../interfaces/DharmaKeyRingImplementationV0Interface.sol";


/**
* @title DharmaLocksmith
* @author 0age
* @notice This contract provides a helper function for setting new keys on a V0
* Dharma Key Ring.
*/
contract DharmaLocksmith {
/**
* @notice Set a new signing key on a keyring using an existing signature on
* the key ring.
* @param keyRing address The key ring to set the new user signing key on.
* @param newUserSigningKey address The new user signing key.
* @param signature bytes The signature, validated from an existing key and
* signed using a valid message hash.
*/
function setAdditionalKey(
address keyRing, address newUserSigningKey, bytes calldata signature
) external {
// Ensure that a key ring has been provided.
require(keyRing != address(0), "No key ring supplied.");

// Add the new key by providing it as an argument to the key ring.
DharmaKeyRingImplementationV0Interface(keyRing).takeAdminAction(
DharmaKeyRingImplementationV0Interface.AdminActionType.AddDualKey,
uint160(newUserSigningKey),
signature
);
}
}
2 changes: 1 addition & 1 deletion contracts/helpers/ECDSAGroup.sol
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ library ECDSAGroup {
}

// EIP-2 still allows signature malleability for ecrecover(). Remove
// this possibility and make the signature unique.
// this possibility and make the signature unique.
if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {
continue;
}
Expand Down
123 changes: 123 additions & 0 deletions contracts/helpers/FactoryFactFinder.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
pragma solidity 0.5.11;

import "../../interfaces/DharmaSmartWalletFactoryV1Interface.sol";
import "../../interfaces/DharmaKeyRingFactoryV1Interface.sol";
import "../../interfaces/DharmaSmartWalletImplementationV0Interface.sol";


/**
* @title FactoryFactFinder (staging)
* @author 0age
* @notice This contract facilitates determining information on counterfactual
* deployment addresses, as well as current deployment statuses, of Dharma Smart
* Wallet + Dharma Key Ring pairs.
*/
contract FactoryFactFinder {
DharmaSmartWalletFactoryV1Interface private constant _smartWalletFactory = (
DharmaSmartWalletFactoryV1Interface(
0x8D1e00b000e56d5BcB006F3a008Ca6003b9F0033
)
);

DharmaKeyRingFactoryV1Interface private constant _keyRingFactory = (
DharmaKeyRingFactoryV1Interface(
0x06f3342295530DdFF6182f7a40906FD60cd19100
)
);

/**
* @notice View function to find the address of the next key ring address that
* will be deployed when supplying a given initial user signing key. Note that
* a new value will be returned if a particular user signing key has been used
* before.
* @param userSigningKey address The user signing key, supplied as a
* constructor argument.
* @return The future address of the next key ring (with the user signing key
* as its input) and of the next smart wallet (with the key ring address as
* its input).
*/
function getNextKeyRingAndSmartWallet(
address userSigningKey
) external view returns (address keyRing, address smartWallet) {
// Ensure that a user signing key has been provided.
require(userSigningKey != address(0), "No user signing key supplied.");

// Get the next key ring address based on the signing key.
keyRing = _keyRingFactory.getNextKeyRing(userSigningKey);

// Determine the next smart wallet address based on the key ring address.
smartWallet = _smartWalletFactory.getNextSmartWallet(keyRing);
}

/**
* @notice View function to determine whether a given smart wallet has been
* deployed as well as whether the corresponding keyring contract still needs
* to be deployed for the smart wallet.
* @return Two booleans, indicating if the smart wallet and/or the keyring are
* deployed or not, and the address of the keyring. Note that keyRing and
* keyRingDeployed will always return the null address and false in the event
* that the smart wallet has not been deployed yet.
*/
function getDeploymentStatuses(
address smartWallet
) external view returns (
bool smartWalletDeployed,
bool keyRingDeployed,
address keyRing
) {
// Ensure that a smart wallet address has been provided.
require(smartWallet != address(0), "No smart wallet supplied.");

// Determine if the smart wallet has been deployed.
smartWalletDeployed = _hasContractCode(smartWallet);

// Get keyring address and deployment status if smart wallet is deployed.
if (smartWalletDeployed) {
keyRing = DharmaSmartWalletImplementationV0Interface(
smartWallet
).getUserSigningKey();

keyRingDeployed = _hasContractCode(keyRing);
}
}

/**
* @notice View function for deriving the message hash that must be signed in
* order to add a new key to a given key ring that has not yet been deployed
* based on given parameters. Note that V0 does not include a prefix when
* constructing the message hash.
* @param keyRing address The yet-to-be-deployed keyring address.
* @param additionalUserSigningKey address The additional user signing key to
* add.
* @return The message hash to sign.
*/
function getFirstAdminActionHash(
address keyRing, address additionalUserSigningKey
) external view returns (bytes32 hash) {
hash = keccak256(
abi.encodePacked(
keyRing, uint256(0), uint256(0), uint160(additionalUserSigningKey)
)
);
}

/**
* @notice View function to determine if a given account contains contract
* code.
* @return True if a contract is deployed at the address with code.
*/
function hasContractCode(address target) external view returns (bool) {
return _hasContractCode(target);
}

/**
* @notice Internal view function to determine if a given account contains
* contract code.
* @return True if a contract is deployed at the address with code.
*/
function _hasContractCode(address target) internal view returns (bool) {
uint256 size;
assembly { size := extcodesize(target) }
return size > 0;
}
}
10 changes: 5 additions & 5 deletions contracts/helpers/IndestructibleRegistry.sol
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ contract IndestructibleRegistry {
uint256 size;
assembly { size := extcodesize(target) }
require(size > 0, "No code at target.");

// Get code at the target and the location data starts and ends in memory.
uint256 dataStart;
bytes memory extcode = new bytes(size);
Expand All @@ -100,14 +100,14 @@ contract IndestructibleRegistry {
}
uint256 dataEnd = dataStart + size;
require (dataEnd > dataStart, "SafeMath: addition overflow.");

// Look for any reachable, impermissible opcodes.
bool reachable = true;
uint256 op;
for (uint256 i = dataStart; i < dataEnd; i++) {
// Get the opcode in question.
assembly { op := shr(0xf8, mload(i)) }

// Check the opcode if it is reachable (i.e. not a constant or metadata).
if (reachable) {
// If execution is halted, mark opcodes that follow as unreachable.
Expand All @@ -127,7 +127,7 @@ contract IndestructibleRegistry {
i += (op - 95);
continue;
}

// If opcode is impermissible, return true - potential destructibility!
if (
op == 242 || // callcode
Expand All @@ -137,7 +137,7 @@ contract IndestructibleRegistry {
return true; // potentially destructible!
}
} else if (op == 91) { // jumpdest
// Whenever a JUMPDEST is found, mark opcodes that follow as reachable.
// Whenever a JUMPDEST is found, mark opcodes that follow as reachable.
reachable = true;
}
}
Expand Down
4 changes: 2 additions & 2 deletions contracts/helpers/RelayMigrator.sol
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import "../../interfaces/RelayContractInterface.sol";
* wallet address will be recorded for each relay contract. Once a smart
* wallet has been deployed for each relay contract, the deployment phase
* will be marked as ended, and the final group of deployed smart wallets
* should be verified by calling `getTotalDeployedSmartWallets` and
* should be verified by calling `getTotalDeployedSmartWallets` and
* `getRegisteredRelayContract`, making sure that each relay contract has a
* corresponding smart wallet, and updating that information for each user.
* - Phase three: Approval Assignment. Each relay contract will need to call
Expand Down Expand Up @@ -168,7 +168,7 @@ contract RelayMigrator is Ownable {
);

assembly { codeHash := extcodehash(relayContract) }

require(
codeHash == _RELAY_CODE_HASH_ONE ||
codeHash == _RELAY_CODE_HASH_TWO ||
Expand Down
Loading

0 comments on commit 185cd27

Please sign in to comment.