Giter VIP home page Giter VIP logo

ambiretech / adex-protocol-eth Goto Github PK

View Code? Open in Web Editor NEW
49.0 49.0 24.0 8.88 MB

Ethereum implementation of the Ambire Protocol: Ambire Wallet contracts and AdEx payment channels

Home Page: https://www.ambire.com

License: MIT License

JavaScript 53.69% Solidity 45.42% Shell 0.89%
adex advertising defi ethereum metatx payment-channels smart-wallet solidity state-channels wallet walletconnect

adex-protocol-eth's People

Contributors

0xdex18 avatar dependabot[bot] avatar elpiel avatar ivopaunov avatar ivshti avatar jordan-enev avatar jtakalai avatar maskln avatar samparsky avatar shteryana avatar simzzz avatar stojnovsky avatar touhonoob avatar vanina-iv avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

adex-protocol-eth's Issues

Ethereal Hackathon Bounty: AdEx: generate identity proxy bytecode without solc

IdentityDeployProxy.js: look into ways of generating bytecode w/o solc

Challenge description:

We use an Identity contract that reprensets each user (similar to multisig contracts, e.g. Gnosis safe); to save gas when deploying an identity for each user, we use delegatecall-based proxies.

The proxy contract bytecode is generated by the following JS: https://github.com/AdExNetwork/adex-protocol-eth/blob/master/js/IdentityProxyDeploy.js, for each user

There are comprehensive tests in test/TestIdentity that show how that API is supposed to be used.

However, this JS library uses the full solc, which has some issues:

  • shipping full emscripten/solc binaries imposes runtime overhead and more load time
  • we ran into crashes/other issues while using solc.js in a web browser environment
  • ethereum/solc-js#34 ; it's definitely not fixed, they just fixed it in the binary
  • it is an engineering overkill to ship the full solc for compiling a few bits of assembly
  • this will be ran server-side and on the front-end, so performance matters

So, the challenge is to rewrite that JS to generate bytecode that does the same, but without having to ship solc (potentially by using a lighter weight EVM assember)

Submission requirements:

  • Tests in test/TestIdentity pass without modification
  • the functionality of js/IdentityProxyDeploy.js is preserved
  • dependency graph is reduced and/or heavyweight solc.js is removed

Submission deadline:

  • April 30

Judging criteria:

  • Best submission
  • Correctness and elegance of the solution
  • Performance of the solution
  • contributions to other open-source packages will be appreciated

Judging date:

  • April 30

Bounty:

  • 1500 DAI

extra/UserContract

simple contract based on/derived from the gnosis safe that allows gas abstractions for a user, and scheduled withdrawals

other implementations of gas abstractions seem dangerously complicated...

what we need is:

  • a multisig accepting signed messages
  • a layer allowing the relayer to earn revenue
  • a special type of message that allows the relayer to call channelWithdraw with any arguments for a certain channel; this allows scheduled withdrawals and does not have negative trust implications since channelWithdraw always withdraws to msg.sender; the only thing is, this message should allow only one such call, otherwise the relayer can withdraw your acc via tx fees

Research EIP-712 compatibility

so far, the repo should be theoretically compatible with EIP 712 signatures according ot the latest spec

to see if it's so in practice, review metamask and test

potentially have tests which use metamask's source code to sign EIP 712 msgs

also see AmbireTech/adex-platform#31

Registry: staking contract

Implement a contract to stake ADX

It should:

  • allow depositing and withdrawing ADX
  • allow opening bonds against certain validators; the bound should contain an amount and validator address
  • closing bonds should be time locked
  • you can only withdraw what's in the bond
  • an address that represents a bridge to substrate (see https://github.com/AdExNetwork/adex-protocol/issues/7#issuecomment-446875892) will be able to slash bonds (slasherAddr)

Other ideas:

  • auxiliary contract that will allow buying ADX with ETH and depositing that

ENS registrar for user subdomains

The goal is to allow users to easily register an ENS subdomain through their Identity contracts.

This would not require any changes to the Identity, as execute can be used to trigger the name registrarion; it would simply require a registrar that will be set for adex.eth:

https://github.com/ensdomains/ens/blob/master/contracts/FIFSRegistrar.sol

See this as an example of what the Identity will do, once the user decides to register a username: https://github.com/UniversalLogin/UniversalLoginSDK/blob/master/universal-login-contracts/contracts/utils/ENSUtils.sol

Unlike the Universal login SDK, we won't force users into picking a username, it will be an entirely optional step that happens after registration

This is a simple task, but must be done within the team (hence no gitcoin-candidate) cause it requires nailing down a few important details; using a simple registrar won't be completely trustless, as we can change it at any time; to fix this, there must be a SC that owns the name completely; we will start with the simple FIFSRegistrar, and this could be an upgrade later down the line

a more trustless solution can be seen here: https://github.com/ensdomains/subdomain-registrar ; we won't use this, since we simply want a FIFSregistrar for our users

requirements:

  • inability to register names that are too short (they will be reserved) - will be controlled in the platform initially
  • certain level of upgradability so we can add shorter names later on - we can always update the controller
  • migration plan to a trustless setup (where the contract would own the adex.eth domain) - we can always update the controller

see also:

consider ways of fixing issue 6 from g0 group audit

Anybody can frontrun owner generated call of deployAndFund by either calling deploy or deployAndExecute making the owner's transaction fail. This forces the factory owner to fund the Identity contract in a different way, forcing additional transaction costs.

proposed way to fix this:

  • ignore errors when deploying
  • skip deploying if already deployed (seems much better)
  • two-phase commit system
  • salt must be related in some way to the caller; this is bad cause the user can't deploy the contract themselves if they have to

For now, option 2 is the frontrunner (lol)

update to Solidity v0.5.5

features important gas cost optimizations, esp for the ABIEncoder v2 which we use for almost everything

Should we not allow publisher == advertiser?

currently it's possible for an advertiser to be their own publisher

in effect, they're basically doing a no-op, other than paying the validators

while it looks like something that we maybe shouldn't allow, this may have usecases actually, like if the same entity is acting both as a publisher and an advertiser, but nominates a third party validator to keep their data

Ethereal Hackathon Bounty: AdEx: Uniswap fork with SafeERC20

Challenge description:

Uniswap is revolutionary - it showed us that it's possible to build an efficient and user friendly exchange on Ethereum by making the right design decisions.

However, it's smart contracts were built in vyper - which is not a bad thing, but coupled with the a popular bug in many erc20 contracts, means it's not usable for a lot of 2017 erc20 tokens, including ADX

The challenge is to build a uniswap version in solidity (perhaps based on https://github.com/PhABC/uniswap-solidity) that uses our own https://github.com/AdExNetwork/adex-protocol-eth/blob/master/contracts/libs/SafeERC20.sol library

This would come in handy to exchange ADX to ETH and vice versa; it should be able to interoperate with Uniswap itself, probably by wrapping the factory+registry - using the solidity-based market contracts for buggy ERC20 tokens and using the uniswap markets for non-buggy

More links:

https://twitter.com/phabcd/status/1101672268189581312?s=21
PhABC/uniswap-solidity#1
https://medium.com/coinmonks/missing-return-value-bug-at-least-130-tokens-affected-d67bf08521ca

Submission requirements:

  • Uniswap smart contracts that work with SafeERC20
  • should be ABI compatible with uniswap itself
  • should have comprehensive tests

Submission deadline:

  • April 30

Judging criteria:

  • Best submission
  • Correctness and security
  • gas-efficient and well designed solidity contracts
  • contributions to other open-source packages will be appreciated

Judging date:

  • April 30

Bounty:

  • 300 DAI

Design limitation: smart contracts can’t be advertisers

Because advertisers need to sign messages, they can’t be smart contracts

Same applies to validators but it’s less of a problem

For now we are intentionally not addressing this problem, since there’s not a lot of practical use cases; if we need it, we can add a special function that registers a bid on chain, like in DEXY

Alternatively we can just solve this in the cosmos/polkadot versions; eg allow IBC messages to open bids too

[OBSOLETE] ValidatorURLRegistry

Problem

If a validator permanently loses access to their domain name, or in some other way loses control over their endpoint URL (e.g. https://scratchy.validator.network), then all campaigns with it are permanently frozen and can't advance; no funds will be lost, but it's unpleasant

Solution

We deploy a separate ValidatorURLRegistry contract, which allows validators to override the endpoint they set in the campaigns spec

The contract will expose a mapping endpoints of the type address => string, and you'd be able to set the endpoint for msg.sender

NOTE: whether the validator ID is always an ethereum address or it would allow ENS, depends on the adapter implementation; initially we only support addresses

Identity: more events?

consider more events, potentially for: when execute relays transactions, when executeRoutine relays transactions, and when a routine auth fee is claimed

tests failing cause of incorrect err messages

  16 passing (18s)
  3 failing

  1) Contract: Identity
       relay a tx:

      error message is incorrect
      + expected - actual

      -VM Exception while processing transaction: out of gas
      +VM Exception while processing transaction: revert ONLY_IDENTITY_CAN_CALL
      
      at expectEVMError (test/index.js:11:10)
      at <anonymous>
      at process._tickCallback (internal/process/next_tick.js:189:7)

  2) Contract: Identity
       execute by sender:

      error message is incorrect
      + expected - actual

      -VM Exception while processing transaction: revert
      +VM Exception while processing transaction: revert PRIVILEGE_NOT_DOWNGRADED
      
      at expectEVMError (test/index.js:11:10)
      at <anonymous>
      at process._tickCallback (internal/process/next_tick.js:189:7)

  3) Contract: Identity
       channelOpen and channelWithdrawExpired, via routines:

      error message is incorrect
      + expected - actual

      -VM Exception while processing transaction: revert
      +VM Exception while processing transaction: revert NOT_EXPIRED
      
      at expectEVMError (test/index.js:11:10)
      at <anonymous>
      at process._tickCallback (internal/process/next_tick.js:189:7)

the weird thing is that all other cases do return correct messages

Identity: restricted addresses that can only open channels with certain validators (or publisher platforms)

this should perhaps be a part of future iterations of the protocol, and would play nicely with the https://github.com/adexnetwork/adex-protocol#registry

the idea is to allow identity instances in which an address is allowed to open campaigns, but only with certain validators

this could be especially useful for grants that are only meant to be spent on AdEx advertising - e.g. you might get a grant on a SC that you can only redeem if you're calling into that SC through an Identity instance that's restricted in that way

the restricted validator set can be based on data from the Registry - e.g. the leader can only be one of the top N nodes from the advertiser side, and the follower can be only one of top N of the publisher side

Rename publisher/advertiser to supply/demand

Rename publisher/advertiser to supply/demand,

or, in the case of commitments, we can rename publisher/advertiser to beneficiery/giver

the rationale is that the interaction is not necessarily directly between publishers and advertisres

Design limitation: trust issues when using with 2 validators

If this is used the same way as the old protocol, with 2 validators (publisher and advertiser), only 1 vote is required, which means the publisher can vote themselves and that will be sufficient.

This means, the dapp must always nominate a third validator.

extra/ValidatorRegistry [TO BE RENAMED]

make an extra/ dir where we put everything not part of the OUTPACE stuff but still helpful to the protocol

this idea is for a ValidatorRegistry, where a validator can register their signing address against their wallet

Like so:

mapping (address => address)

The point of that is to allow validators to earn fees in different wallets than the ones they're using for signing

This registry component can also allow validators to use ENS and/or register their HTTPS endpoint(s) on-chain

Complete tests: cases that should revert, timeouts

there are a number of TODOs scattered over test/TestAdExCore.js regarding negative cases (reverts, commitment timeouts) that should be tested

it would require writing the tests a bit smarter to avoid copypasta, but that should be trivial

Identity: deployAndExecute

consider implement a deployAndExecute function, which would, in that order

  1. deploy a new Identity
  2. execute signed transactions on it
  3. withdraw the relayer fee

the problem is that the order of 1 and 3 is fixed by the way identity contracts are created, so we cannot do 2 between them

as a solution, we can pay out the fee as an executable transaction

all tests that are mentioned as TODOs in tests/

  • core: ensure we can't withdraw after the channel is expired
  • core: we can't withdrawExpired twice
  • core: more checks for withdrawExpired test
  • core: withdrawals: check mtree with 1, 2, 3 elements
  • core: test if only the difference is withdrawn
  • core: ensure we cannot wihdraw more than the channel deposit
  • core: can't withdraw with a lower value leaf than previous withdraw
  • core: withdrawn expired will only return the remaining
  • identity: multiple transactions
  • identity: multiple feeTokenAddr will fail
  • identity: set gasLimit manually
  • identity: routines: op1, withdraw expired

User-friendly signed messages w/o EIP712

We already have the ADEX signature type which prefixes messages with a user friendly message (By signing this message, you acknowledge signing an AdEx bid with the hash:)

However, we still show the raw bytes, which in ASCII look fairly ugly/scary; hex would be friendlier.

PLEASE NOTE: currently the internal consensus is to NOT use hex strings, but stick with the raw value; using hex strings adds too much on-chain complexity

This is an approach used by airswap, and spankchain:

https://etherscan.io/address/0xf91546835f756da0c10cfa0cda95b15577b84aa7#code

        bytes memory sig = hexstrToBytes(substring(_sig, 2, 132));

    // @dev Converts an hexstring to bytes
    function hexstrToBytes(string _hexstr) public pure returns (bytes) {
        uint len = bytes(_hexstr).length;
        require(len % 2 == 0);

        bytes memory bstr = bytes(new string(len / 2));
        uint k = 0;
        string memory s;
        string memory r;
        for (uint i = 0; i < len; i += 2) {
            s = substring(_hexstr, i, i + 1);
            r = substring(_hexstr, i + 1, i + 2);
            uint p = parseInt16Char(s) * 16 + parseInt16Char(r);
            bstr[k++] = uintToBytes32(p)[31];
        }
        return bstr;
    }

    // @dev Parses a hexchar, like 'a', and returns its hex value, in this case 10
    function parseInt16Char(string _char) public pure returns (uint) {
        bytes memory bresult = bytes(_char);
        // bool decimals = false;
        if ((bresult[0] >= 48) && (bresult[0] <= 57)) {
            return uint(bresult[0]) - 48;
        } else if ((bresult[0] >= 65) && (bresult[0] <= 70)) {
            return uint(bresult[0]) - 55;
        } else if ((bresult[0] >= 97) && (bresult[0] <= 102)) {
            return uint(bresult[0]) - 87;
        } else {
            revert();
        }
    }

Allow easy retrieval of the vote

this will be convenient if we want other SCs to check the outcome, for example if the vote is a merkle root of a tree containing detailed info about the execution of that commitment

Identity: recovery DAO for Quick accounts

The idea is to allow users with quick (limited) accounts to recover their account

The process will work as follows:

  • when the user makes a quick account, we create two wallets: wallet A and wallet B; we create an identity that can be controlled by wallet A and the recovery contract (both having full permissions); we sign a message, using wallet A, that will later allow the recovery contract to call into the identity and add wallet B, and sends that message to AdEx (either the market or the relayer); they receive the seed to wallet B on email, directly from the browser
  • if the user loses wallet A, they will send a request to the AdEx market/relayer, which will check the activity of the account and if it's really inactive, send the signed message to the recovery contract
  • the recovery contract verifies the message and calls into the identity, adding wallet B
  • user can now use wallet B and withdraw their funds

looking for ways to make this simpler

this requires two potential changes to the identity contract:

  • accept execute() w/o a message, but directly through msg.sender, allowing smart contracts to call into the identity
  • have a lastInteractedWith public timestamp

AdEx: Grow Ethereum: generate identity proxy bytecode without solc

IdentityDeployProxy.js: look into ways of generating bytecode w/o solc

Challenge description:

(for the previous challenge, and previous discussion, see #62)

We use an Identity contract that reprensets each user (similar to multisig contracts, e.g. Gnosis safe); to save gas when deploying an identity for each user, we use delegatecall-based proxies.

The proxy contract bytecode is generated by the following JS: https://github.com/AdExNetwork/adex-protocol-eth/blob/master/js/IdentityProxyDeploy.js, for each user

There are comprehensive tests in test/TestIdentity that show how that API is supposed to be used.

However, this JS library uses the full solc, which has some issues:

  • shipping full emscripten/solc binaries imposes runtime overhead and more load time
  • we ran into crashes/other issues while using solc.js in a web browser environment
  • ethereum/solc-js#34 ; it's definitely not fixed, they just fixed it in the binary
  • it is an engineering overkill to ship the full solc for compiling a few bits of assembly
  • this will be ran server-side and on the front-end, so performance matters

So, the challenge is to rewrite that JS to generate bytecode that does the same, but without having to ship solc

The best solution would be use a simple EVM assembler, and to our knowledge, there's no such solution that's lightweight, embeddable in a web-based front-end, and well maintained

Such an assembler could be implemented in a web-friendly language (JS, TypeScript) or a language that compiles to WASM (Rust). Any solutions in languages other than JS/TypeScript/Rust will not be accepted.

Submission requirements:

  • Tests in test/TestIdentity pass without modification
  • the functionality of js/IdentityProxyDeploy.js is preserved
  • dependency graph is reduced and/or heavyweight solc.js is removed

Submission deadline:

  • August 19

Judging criteria:

  • Best submission
  • Correctness and elegance of the solution
  • Performance of the solution
  • contributions to other open-source packages will be appreciated

Judging date:

  • August 19

Bounty

  • 2000 DAI

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.