Security News
New Python Packaging Proposal Aims to Solve Phantom Dependency Problem with SBOMs
PEP 770 proposes adding SBOM support to Python packages to improve transparency and catch hidden non-Python dependencies that security tools often miss.
@authereum/contracts
Advanced tools
Ethereum smart contracts for Authereum
Check out the Authereum contracts bug bounty program here!
The Authereum contracts are necessary pieces of the Authereum ecosystem. Users of the Authereum accounts own a proxy contract that points to an upgradeable logic contract. The contracts are organized in the following directories:
When a user signs up for an account on authereum.com, a proxy contract (upgradeability/AuthereumProxy.sol
) is created for them through the Authereum proxy factory (upgradeability/AuthereumProxyFactory.sol
). The creation of the proxy simply points the proxy to the latest Authereum account logic (implementation) address, initializes the proxy for that logic address, and gives the proxy and ENS subdomain (*.auth.eth).
Each proxy is fully owned by the user who created it, and Authereum has no custody or control over it at all.
The proxies are upgradeable with the proxy-delegate pattern, which simply means they can point to a new logic address and initialize themselves at that address. The user controls the upgrade and they are the only ones that can perform the upgrade.
The system is designed to be transacted with by meta transactions. Authereum users will sign messages that are sent to relayers who will broadcast the transactions.
There are two types of keys that interact with the contracts: auth keys and login keys. Auth keys have the most power and can perform administrative actions such as adding/removing auth keys and upgrading the account. Login keys are more restricted and can only send transactions.
A core component of the system is the signing of keys. Auth keys and login keys sign messages off-chain, and these messages and their signatures are passed into the contracts so that the signer can recovered and verified on-chain. There are two types of signatures checked:
authKey.sign(loginKey, data)
. Both pieces of data and both signatures are sent to the transaction. The login key and auth key are recovered on-chain, and the contract verifies that these addresses are correct.More information can be found here.
The account
directory contains the logic contract for an Authereum Account. It is a single contract with AuthereumAccount.sol
being the bottom-most contract on an inheritance tree. A user's proxy will point to this deployed contract and will use it for its logic.
This contract is upgradeable. Because of this, it is designed in such a way as to avoid overwriting any state variables. accounts/state/
, accounts/initializer/
, and accounts/event/
have been separated out into subdirectories that each have the contract's state, initializers, and events, respectively. Any upgrades to the contract will create a new version (e.g. AccountStateV2.sol) that gets inherited, in order, as to completely avoid overwriting any state. The initializer functions are meant to be called when upgrading a contract and are protected from being called multiple times with the lastInitializedVersion
state variable. Technically the contract events are able to be upgraded/overwritten without causing problems, but we put them in their own directory and will treat them similar to state upgrades. This is for cleanliness of code and so that the initializers can emit events.
In normal circumstances, transactions are meant to be sent by a relayer to one of two functions: executeMultipleAuthKeyMetaTransactions()
and executeMultipleLoginKeyMetaTransactions()
. See Top Level Design Decisions for more information about the different keys. These transactions perform the following functions:
The following section will break down each point above.
Atomic Transactions - The Authereum contracts perform atomic transactions within their own transaction. In the context of an Authereum transaction, this means that transactions sent to an Authereum contract perform a call
back to itself. The reason for this is to be able to revert within a transaction without reverting the entire transaction. This allows for the unwinding of state if a transaction fails while still allowing a relayer to be refunded.
Verify Signatures - See Top Level Design Decisions for more information about the signing. In short, signatures are created off-chain that are verified on-chain. This was done for efficiency and to minimize the number of on-chain transactions.
Execute Transactions - Authereum users can send batched transactions. These are multiple transactions that are all batched into one, single on-chain transaction. See here for more information. The Authereum contracts loop through each passed-in transaction and executes them with a call
.
Refunds - Most Authereum transactions should be sent by a relayer. Because of this, Authereum transactions refund the relayer who broadcasts the transaction at the conclusion of their transaction based on the amount of gas that was used. Refunds can be paid in ETH or tokens. It is expected that the relayer will not broadcast transactions that will be detrimental to themselves. The feeTokenRate
is passed in by the user and is used to calculate the number of tokens that are paid to the relayer in a refund. It is expected that a relayer will not send a transaction with a token rate that they do not agree with.
There is a gasOverhead
parameter that is passed into these functions as well. The value of this parameter is meant to be calculated off-chain and passed into the transaction. It represents the gas overhead that is not taken into account when calculating a refund. This may include the gas cost of the calldata
, as well as any additional logic that is not captured by the gas calculations.
Upgradeability logic lives within this contract as well. In order to perform an upgrade, a user must send a transaction to executeMultipleAuthKeyMetaTransactions()
that, in turn, calls its own upgradeToAndCall()
function.
Finally, 721 and 1125 hooks are used in order to receive those types of tokens in the Authereum contracts.
Authereum's contracts are upgradeable. Each Authereum user owns a proxy (AuthereumProxy.sol
) that points to their desired logic contract. This contract's sole function is to provide a fallback function that delegates calls to the proxy's logic contract. All Authereum user transactions go through this fallback.
Each proxy is created by the Authereum proxy factory (AuthereumProxyFactory.sol
). The Authereum proxy factory creates an account when createProxy()
is called. This function creates a proxy with create2
, initializes it, and registers a subdomain for the proxy. When a user creates an account on a later version of the Authereum contracts, they will have to iterate through each previous version's initializer. Because of this, the createProxy()
function loops through each piece of the initialize data.
The AuthereumEnsResolverProxy.sol
is nearly identical to the AuthereumProxy.sol
contract and is used for upgrading the Authereum ENS Resolver Proxy.
The Authereum contracts support "module" contracts that can be used to introduce additional functionality to an Authereum account. A module contract is added to an Authereum account by adding its address as an Auth Key. Because modules may contain critical functionality (e.g. the RecoveryModule), Login Keys should not be able to interact with modules. To prevent this, a check in LoginKeyMetaTxAccount.sol
will revert the transaction if a Login Key's transaction's destination is an Auth Key, which may be a module. In addition, when designing modules, care should be taken to ensure Login Key's cannot interact with a module before it's added to an account as an Auth Key. Both the RecoverModule and DelegateKeyModule prevent this with the onlyWhenRegisteredModule
modifier.
AuthereumProxy.sol
will remain at version 0.5.16
so that the bytecode of the contract does not change. Other contracts that this contract interacts with can be upgraded.feeTokenRate
that the relayer does not accept as a true rate_lockedParameters
and _lockedParameterValues
are equal to the actual number of parameters taken by the function being registered. In addition, dynamically-sized parameters cannot be locked but this is not enforced on-chain. When registering a Delegate Key, care should be taken to ensure that _lockedParameters
and _lockedParameterValues
equal the number of parameters in the function being registered and that none of the parameters being locked are dynamically-sized.onlySelf
or onlyAuthKeySenderOrSelf
should not be accessible by a Login Key.validationContract
to address(0)
. It is expected that relayers who process transactions validate these restrictions off-chain, if desired.Environment variables:
NETWORK_NAME=kovan
ETH_HTTP_PROVIDER_URI='https://kovan.rpc.authereum.com'
SENDER_ADDRESS=0x...
SENDER_PRIVATE_KEY=0x...
LOGIC_ADDRESS=0x...
You may also set the config by invoking the setConfig(config)
static method.
All the versioning in the Authereum system will use Unix timestamps. A dictionary will be kept that maps version numbers to human-readable names.
Advantage of Unix Timestamp:
Design Decisions:
Note: this requires a ganache-cli
version with the muirGlacier compiler. Please use ganache-cli@6.9.0
or greater.
# In terminal 1
npm run ganache
# In terminal 2
npm run test
The Authereum proxy's should all share the same bytecode from 'Compiler version 0.5.12+commit.7709ece9'. All of these proxy's should have the following bytecode with the respective, padded logic contract address appended to it:
0x60806040526040516103753803806103758339818101604052610025919081019061006c565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc60001b905081815550506100de565b600081519050610066816100c7565b92915050565b60006020828403121561007e57600080fd5b600061008c84828501610057565b91505092915050565b60006100a0826100a7565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6100d081610095565b81146100db57600080fd5b50565b610288806100ed6000396000f3fe6080604052600436106100295760003560e01c80635bea7d5d1461006e5780635c60da1b14610099575b600080369050141561003a5761006c565b60006100446100c4565b90503660008037600080366000845af43d6000803e8060008114610067573d6000f35b3d6000fd5b005b34801561007a57600080fd5b506100836100f5565b6040516100909190610191565b60405180910390f35b3480156100a557600080fd5b506100ae6100c4565b6040516100bb9190610176565b60405180910390f35b6000807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc60001b9050805491505090565b6040518060400160405280600a81526020017f323031393130323530300000000000000000000000000000000000000000000081525081565b610137816101cf565b82525050565b6000610148826101b3565b61015281856101be565b9350610162818560208601610201565b61016b81610234565b840191505092915050565b600060208201905061018b600083018461012e565b92915050565b600060208201905081810360008301526101ab818461013d565b905092915050565b600081519050919050565b600082825260208201905092915050565b60006101da826101e1565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60005b8381101561021f578082015181840152602081019050610204565b8381111561022e576000848401525b50505050565b6000601f19601f830116905091905056fea365627a7a72315820df4401333fb8c26a38547c751ff4c528d95f9c5a191e6bc81f110b41250720046c6578706572696d656e74616cf564736f6c634300050c0040
This update was a routine update to prepare for another audit by G0 Group.
General
loginKeyRestrictionData
to loginKeyRestrictionsData
authereum.eth
to auth.eth
istanbul
compiler_atomicExecuteMultipleMetaTransactions
self
onlyAuthKeySender
modifiername
variable to contractsauthereumVersion
to version
implementation()
implementation()
and upgradeToAndCall()
to IAuthereumAccount.sol
executeMultipleTransactions()
function and scope it to auth keysexecuteMultipleMetaTransactions()
function scope to selfTests
This update was in response to samczsun's disclosure:
Bugfixes
This update was in response to our Quantstamp audit.
General
Bugfixes
executeMultipleMetaTransactions()
Bugfixes
General
General
_feeTokenAddress
and _feeTokenRate
Bugfixes
General
General
name
version
initCode
directly into the constructorinitData
in the create2
salt to validate auth keyGeneral
initCode
setter and change eventauthereumEnsManager
setter and change eventGeneral
General
name
version
name
to _name
General
General
General
version
General
text
and contenthash
to interfacetext
and contenthash
as setter and getterGeneral
General
General
General
Why am I getting the following when I run a test?
connection not open on send()
connection not open
npm run truffle-reset
8545
or 9545
)Update: 11/19/19 - This error is related to using WebSockets. If this error persists, try using https instead, if possible.
Why is my test failing on a simple test? It seemingly reverts even when it shouldn't.
Why are my tests not running with Returned values aren't valid, did it run Out of Gas?
You are trying to deploy on a different network. Try changing the .env
file to reflect the network you are trying to deploy on.
Delete the build
folder and run truffle compile && truffle migrate --reset
Why am I getting the following error when running tests?
Error: EnsRegistry error: contract binary not set. Can't deploy new instance.
This contract may be abstract, not implement an abstract parent's methods completely
or not invoke an inherited contract's constructor correctly
Delete the build
folder and run truffle compile && truffle migrate --reset
Why are my tests not running at all (and the output says 0 passing)
it(){}
). It is
likely that you only have describe(){}
and/or context(){}
.What are the event topics for each of the events in AuthereumAccount.sol?
event Upgraded(address indexed implementation);
: 0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b
event CallFailed(string reason);
: 0xb5e1dc2ddc0e1a0221e00b3c0446f36b707001d3ac7cfb494259863fdef7ccd7
event AuthKeyAdded(address indexed authKey)
: 0xb020719d16d3c4de45a91f9c329aa61d5bad3f44f760840c8d5d82d4cd3bcc33
event AuthKeyRemoved(address indexed authKey)
: 0xbe55f9add9abe657e689a4a84a31854310f260c7e2610bcd22440e3ec3a836a4
What is the best way to verify my contract on Etherscan?
truffle run verify xxx@yyy --network zzz
truffle run verify AuthereumAccount@0x2e1723d1DFa2947f0d08D5c5D214b71deF4f951F --network mainnet
How can I retroactively verify my contract on Etherscan if it has been a while since I deployed it.
git blame
. Once the commit is found, do the following:
git checkout <commit>
truffle-plugin-verify
pluginnpm run ganache
rm -rf build && truffle compile && truffle migrate
truffle run verify xxx@yyy --network zzz
Why does my deployed address not match my calculated address?
src/constants
. If you updated the compiler, this will need changed, along with the code that uses that data elsewhere.Why do I keep getting "Error: Returned error: the tx doesn't have the correct nonce. account has nonce of: 1 tx has nonce of: 0" when I run tests
FAQs
Ethereum smart contract for Authereum
The npm package @authereum/contracts receives a total of 103 weekly downloads. As such, @authereum/contracts popularity was classified as not popular.
We found that @authereum/contracts demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 3 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
PEP 770 proposes adding SBOM support to Python packages to improve transparency and catch hidden non-Python dependencies that security tools often miss.
Security News
Socket CEO Feross Aboukhadijeh discusses open source security challenges, including zero-day attacks and supply chain risks, on the Cyber Security Council podcast.
Security News
Research
Socket researchers uncover how threat actors weaponize Out-of-Band Application Security Testing (OAST) techniques across the npm, PyPI, and RubyGems ecosystems to exfiltrate sensitive data.