Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,6 @@ artifacts
typechain
.openzeppelin
flatten
typechain
types

99 changes: 99 additions & 0 deletions contracts/v2/accounts/default/ECDSA.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
// SPDX-License-Identifier: MIT

pragma solidity ^0.7.0;

/**
* @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.
*
* These functions can be used to verify that a message was signed by the holder
* of the private keys of a given address.
*/
library ECDSA {
/**
* @dev Returns the address that signed a hashed message (`hash`) with
* `signature`. This address can then be used for verification purposes.
*
* The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:
* this function rejects them by requiring the `s` value to be in the lower
* half order, and the `v` value to be either 27 or 28.
*
* IMPORTANT: `hash` _must_ be the result of a hash operation for the
* verification to be secure: it is possible to craft signatures that
* recover to arbitrary addresses for non-hashed data. A safe way to ensure
* this is by receiving a hash of the original message (which may otherwise
* be too long), and then calling {toEthSignedMessageHash} on it.
*/
function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {
// Check the signature length
if (signature.length != 65) {
revert("ECDSA: invalid signature length");
}

// Divide the signature in r, s and v variables
bytes32 r;
bytes32 s;
uint8 v;

// ecrecover takes the signature parameters, and the only way to get them
// currently is to use assembly.
// solhint-disable-next-line no-inline-assembly
assembly {
r := mload(add(signature, 0x20))
s := mload(add(signature, 0x40))
v := byte(0, mload(add(signature, 0x60)))
}

return recover(hash, v, r, s);
}

/**
* @dev Overload of {ECDSA-recover} that receives the `v`,
* `r` and `s` signature fields separately.
*/
function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) {
// EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature
// unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines
// the valid range for s in (281): 0 < s < secp256k1n ÷ 2 + 1, and for v in (282): v ∈ {27, 28}. Most
// signatures from current libraries generate a unique signature with an s-value in the lower half order.
//
// If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value
// with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or
// vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept
// these malleable signatures as well.
require(uint256(s) <= 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0, "ECDSA: invalid signature 's' value");
require(v == 27 || v == 28, "ECDSA: invalid signature 'v' value");

// If the signature is valid (and not malleable), return the signer address
address signer = ecrecover(hash, v, r, s);
require(signer != address(0), "ECDSA: invalid signature");

return signer;
}

/**
* @dev Returns an Ethereum Signed Message, created from a `hash`. This
* produces hash corresponding to the one signed with the
* https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]
* JSON-RPC method as part of EIP-191.
*
* See {recover}.
*/
function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {
// 32 is the length in bytes of hash,
// enforced by the type signature above
return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash));
}

/**
* @dev Returns an Ethereum Signed Typed Data, created from a
* `domainSeparator` and a `structHash`. This produces hash corresponding
* to the one signed with the
* https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]
* JSON-RPC method as part of EIP-712.
*
* See {recover}.
*/
function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {
return keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash));
}
}
109 changes: 109 additions & 0 deletions contracts/v2/accounts/default/implementation_default.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ pragma experimental ABIEncoderV2;

import { Variables } from "../variables.sol";

import { ECDSA } from "./ECDSA.sol";

interface IndexInterface {
function list() external view returns (address);
}
Expand All @@ -20,8 +22,33 @@ contract Constants is Variables {
// The Account Module Version.
uint256 public constant version = 2;

// constants for EIP712 values
string public constant DOMAIN_SEPARATOR_NAME = "DeFi-Smart-Account";
string public constant DOMAIN_SEPARATOR_VERSION = "2.0.0";

// hashed EIP712 values
bytes32 internal constant DOMAIN_SEPARATOR_NAME_HASHED = keccak256(bytes(DOMAIN_SEPARATOR_NAME));
bytes32 internal constant DOMAIN_SEPARATOR_VERSION_HASHED = keccak256(bytes(DOMAIN_SEPARATOR_VERSION));

bytes32 internal constant TYPE_HASH =
keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)");

// EIP712 typehash for signed hashes used for EIP1271 (`isValidSignature()`)
bytes32 public constant EIP1271_TYPE_HASH = keccak256("DSA(bytes32 hash)");

// "magic value" according to EIP1271 https://eips.ethereum.org/EIPS/eip-1271#specification
bytes4 internal constant EIP1271_MAGIC_VALUE = 0x1626ba7e;

// chainId
uint256 public immutable CHAIN_ID;

constructor(address _instaIndex) {
instaIndex = _instaIndex;
uint256 id;
assembly {
id := chainid()
}
CHAIN_ID = id;
}
}

Expand All @@ -31,6 +58,8 @@ contract Record is Constants {
event LogEnableUser(address indexed user);
event LogDisableUser(address indexed user);
event LogBetaMode(bool indexed beta);
event LogSignedMessage(bytes32 indexed message);
event LogRemoveSignedMessage(bytes32 indexed message);

/**
* @dev Check for Auth if enabled.
Expand All @@ -47,6 +76,29 @@ contract Record is Constants {
return _beta;
}

/**
* @dev Returns the domain separator
*/
function domainSeparatorV4() public view returns (bytes32) {
return
keccak256(
abi.encode(
TYPE_HASH,
DOMAIN_SEPARATOR_NAME_HASHED,
DOMAIN_SEPARATOR_VERSION_HASHED,
CHAIN_ID,
address(this)
)
);
}

/**
* @dev Check is `message` is signed or not
*/
function isSignedMessage(bytes32 message) public view returns (bool) {
return _signedMessages[message];
}

/**
* @dev Enable New User.
* @param user Owner address
Expand Down Expand Up @@ -119,6 +171,63 @@ contract Record is Constants {
) external returns (bytes4) {
return 0xbc197c81; // bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))
}

/**
* @dev Marks a bytes32 `message` (signature digest) as signed, making it verifiable by EIP-1271 `isValidSignature()`.
* @param message data hash to be allow-listed as signed. Input `message` is hashed with `domainSeparatorV4()` according to EIP712 typed data (`EIP1271_TYPE_HASH`)
*/
function signMessage(bytes32 message) external {
require(msg.sender == address(this), "not-self");

// hashing with domain separator mitigates any potential replaying on other networks or other Avocados of the same owner
message = ECDSA.toTypedDataHash(
domainSeparatorV4(),
keccak256(abi.encode(EIP1271_TYPE_HASH, message))
);

_signedMessages[message] = true;

emit LogSignedMessage(message);
}

/**
* @dev Removes a previously `signMessage()` signed bytes32 `message_` (signature digest).
* @param message data hash to be removed from allow-listed signatures
*/
function removeSignedMessage(bytes32 message) external {
require(msg.sender == address(this), "not-self");

delete _signedMessages[message];

emit LogRemoveSignedMessage(message);
}

/**
* @dev Should return whether the signature provided is valid for the provided data
* @param hash Hash of the data to be signed
* @param signature Signature byte array associated with data
*/
function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue) {
// hashing with domain separator mitigates any potential replaying on other networks or other DSA of the same owner
hash = ECDSA.toTypedDataHash(
domainSeparatorV4(),
keccak256(abi.encode(EIP1271_TYPE_HASH, hash))
);

if (signature.length == 0) {
// must be pre-allow-listed via `signMessage()` method
require(_signedMessages[hash], "invalid-signed-message");
} else {
address signer = ECDSA.recover(hash, signature);

if (!_auth[signer]) {
require(_signedMessages[hash], "invalid-EIP-1271-signature");
}
}

return EIP1271_MAGIC_VALUE;
}

}

contract InstaDefaultImplementation is Record {
Expand Down
2 changes: 2 additions & 0 deletions contracts/v2/accounts/variables.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,6 @@ contract Variables {
mapping (address => bool) internal _auth;
// enable beta mode to access all the beta features.
bool internal _beta;
// signed message for EIP-1271
mapping (bytes32 => bool) internal _signedMessages;
}
15 changes: 15 additions & 0 deletions docs/56_deployments.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"InstaIndex": "0x1ba631331503f0486538cb707c6685Cbc6b28944",
"InstaList": "0x6fe05374924830B6aC98849f75A3D5766E51Ef10",
"InstaAccount": "0x20fd0312eDFE3954ec96039B9c644a8074c07F33",
"InstaConnectors": "0xB8266d0afdd49dD8A4283E9FF601ec7743041048",
"InstaEvent": "0x871a1E08845d274c8B52880596180A907B102B67",
"InstaMemory": "0x68206e807c44216B606493e4415Dc78e0dB25a18",
"InstaConnectorsV2Impl": "0x3b9AE61b9feaCBa6C2f58D73aA484D671900bFb4",
"InstaConnectorsV2Proxy": "0x036DeCA530CcF17D4e6BE04e9cc0771AcBc95325",
"InstaConnectorsV2": "0xC867edb3d3337529e176b87Fc29Bf84268D28cb5",
"InstaImplementations": "0x612c5CA43230D9F97a0ac87E4420F66b8DF97e9D",
"InstaAccountV2": "0x68b27A84101ac5120bBAb7Ce8d6b096C961df52C",
"InstaDefaultImplementation": "0x8f3417A9ABe3f5B4D7A85024bDA6E5AcEA1Fb609",
"InstaImplementationM1": "0x8BCC9EbD6432D1A8d77f61AFe032BBAFA4B86458"
}
56 changes: 49 additions & 7 deletions docs/addresses.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"InstaConnectorsV2Proxy": "0x7D53E606308A2E0A1D396F30dc305cc7f8483436",
"InstaConnectorsV2": "0x97b0B3A8bDeFE8cB9563a3c610019Ad10DB8aD11",
"InstaImplementations": "0xCBA828153d3a85b30B5b912e1f2daCac5816aE9D",
"InstaDefaultImplementation": "0x28aDcDC02Ca7B3EDf11924102726066AA0fA7010",
"InstaDefaultImplementation": "0x8F4a8675Ea3a069D1D8280Bd19B802430f8F53be",
"InstaImplementationM1": "0x8a3462A50e1a9Fe8c9e7d9023CAcbD9a98D90021",
"InstaChiefTimelockContract": "0xb3e586BCE929312e8B0685E2c12c1d6dbbcdc370"
}
Expand All @@ -35,7 +35,7 @@
"InstaConnectorsV2Proxy": "0x01fEF4d2B513C9F69E34b2f93Ef707FA9Ff60109",
"InstaConnectorsV2": "0x2A00684bFAb9717C21271E0751BCcb7d2D763c88",
"InstaImplementations": "0x39d3d5e7c11D61E072511485878dd84711c19d4A",
"InstaDefaultImplementation": "0xFc8CcEFeB8bD4e637C787c70F7bf7c2E7Ba9aDdf",
"InstaDefaultImplementation": "0xb8e9ef2a085671858d923aa947cb93b88714d2f8",
"InstaImplementationM1": "0x4aec8c5b1cf3498bef061e13d8e7f646feeb7029",
"InstaImplementationM2": "0x2638c8950e04ef002d083f62aeaa10ee32f1ae60"
}
Expand All @@ -56,7 +56,7 @@
"InstaConnectorsV2Proxy": "0xFD48Bef7F198B561D5198bE19c14142a0574b859",
"InstaConnectorsV2": "0x67fCE99Dd6d8d659eea2a1ac1b8881c57eb6592B",
"InstaImplementations": "0xF3Bb2FbdCDa1B8B6d19f513D69462eA548d0eF12",
"InstaDefaultImplementation": "0x0C25490d97594D513Fd8a80C51e4900252fA18bF",
"InstaDefaultImplementation": "0x0a0a82D2F86b9E46AE60E22FCE4e8b916F858Ddc",
"InstaImplementationM1": "0x3d464f9762493a7Cecb59119a8eCdd54e46b969F"
}
}
Expand All @@ -76,7 +76,7 @@
"InstaConnectorsV2Proxy": "0x6C7256cf7C003dD85683339F75DdE9971f98f2FD",
"InstaConnectorsV2": "0x127d8cD0E2b2E0366D522DeA53A787bfE9002C14",
"InstaImplementations": "0x01fEF4d2B513C9F69E34b2f93Ef707FA9Ff60109",
"InstaDefaultImplementation": "0x39d3d5e7c11D61E072511485878dd84711c19d4A",
"InstaDefaultImplementation": "0x71b6691084681e4234Bda443a27C924012870Daf",
"InstaImplementationM1": "0x28846f4051EB05594B3fF9dE76b7B5bf00431155"
}
}
Expand All @@ -96,7 +96,7 @@
"InstaConnectorsV2Proxy": "0x6C7256cf7C003dD85683339F75DdE9971f98f2FD",
"InstaConnectorsV2": "0x127d8cD0E2b2E0366D522DeA53A787bfE9002C14",
"InstaImplementations": "0x01fEF4d2B513C9F69E34b2f93Ef707FA9Ff60109",
"InstaDefaultImplementation": "0x39d3d5e7c11D61E072511485878dd84711c19d4A",
"InstaDefaultImplementation": "0x497Bc53507DF17e60F731e9534cff74E8BC9DBb8",
"InstaImplementationM1": "0x28846f4051EB05594B3fF9dE76b7B5bf00431155"
}
}
Expand Down Expand Up @@ -136,9 +136,51 @@
"InstaConnectorsV2Proxy": "0x6C7256cf7C003dD85683339F75DdE9971f98f2FD",
"InstaConnectorsV2": "0x127d8cD0E2b2E0366D522DeA53A787bfE9002C14",
"InstaImplementations": "0x01fEF4d2B513C9F69E34b2f93Ef707FA9Ff60109",
"InstaDefaultImplementation": "0x39d3d5e7c11D61E072511485878dd84711c19d4A",
"InstaDefaultImplementation": "0x497Bc53507DF17e60F731e9534cff74E8BC9DBb8",
"InstaImplementationM1": "0x28846f4051EB05594B3fF9dE76b7B5bf00431155"
}
}
},
"plasma": {
"InstaIndex": "0x9926955e0Dd681Dc303370C52f4Ad0a4dd061687",
"InstaList": "0xA9B99766E6C676Cf1975c0D3166F96C0848fF5ad",
"versions": {
"v1": {
"InstaAccount": "0x839c2D3aDe63DF5b0b8F3E57D5e145057Ab41556",
"InstaConnectors": "0xA7c805e4ad4E7B51d2a1eB442B2014a9B63D3703",
"InstaEvent": "0x3254Ce8f5b1c82431B8f21Df01918342215825C2",
"InstaMemory": "0xA4BF319968986D2352FA1c550D781bBFCCE3FcaB"
},
"v2": {
"InstaConnectorsV2Impl": "0x6C7256cf7C003dD85683339F75DdE9971f98f2FD",
"InstaConnectorsV2Proxy": "0x127d8cD0E2b2E0366D522DeA53A787bfE9002C14",
"InstaConnectorsV2": "0x01fEF4d2B513C9F69E34b2f93Ef707FA9Ff60109",
"InstaImplementations": "0x0a0a82D2F86b9E46AE60E22FCE4e8b916F858Ddc",
"InstaAccountV2": "0x39d3d5e7c11D61E072511485878dd84711c19d4A",
"InstaDefaultImplementation": "0x28846f4051EB05594B3fF9dE76b7B5bf00431155",
"InstaImplementationM1": "0x2240770bEc8cB22ed716F2DCcC4F24980A904bC5"
}
}
},
"bsc": {
"InstaIndex": "0x1ba631331503f0486538cb707c6685Cbc6b28944",
"InstaList": "0x6fe05374924830B6aC98849f75A3D5766E51Ef10",
"versions": {
"v1": {
"InstaAccount": "0x20fd0312eDFE3954ec96039B9c644a8074c07F33",
"InstaConnectors": "0xB8266d0afdd49dD8A4283E9FF601ec7743041048",
"InstaEvent": "0x871a1E08845d274c8B52880596180A907B102B67",
"InstaMemory": "0x68206e807c44216B606493e4415Dc78e0dB25a18"
},
"v2": {
"InstaConnectorsV2Impl": "0x3b9AE61b9feaCBa6C2f58D73aA484D671900bFb4",
"InstaConnectorsV2Proxy": "0x036DeCA530CcF17D4e6BE04e9cc0771AcBc95325",
"InstaConnectorsV2": "0xC867edb3d3337529e176b87Fc29Bf84268D28cb5",
"InstaImplementations": "0x612c5CA43230D9F97a0ac87E4420F66b8DF97e9D",
"InstaAccountV2": "0x68b27A84101ac5120bBAb7Ce8d6b096C961df52C",
"InstaDefaultImplementation": "0x8f3417A9ABe3f5B4D7A85024bDA6E5AcEA1Fb609",
"InstaImplementationM1": "0x8BCC9EbD6432D1A8d77f61AFe032BBAFA4B86458"
}
}
}
}
}
Loading
Loading