-
Notifications
You must be signed in to change notification settings - Fork 81
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
Improved ETH connector logic #36
Conversation
* EIP712-Withdraw: fixed encoding rules and order. * EIP712-Withdraw: `verify_withdraw_eip712` returns `true` only if the sender address equals to the address of message signer. * EIP712-Withdraw: update tests. * EIP712-Withdraw: refactoring. * ethabit::encode_token_packed: use right-padded encoding for `Address`. * WithdrawFromEthCallArgs: fixed `amount` type conversion.
…ra-engine into evm-deposit-withdraw
Cool! Nice to see that this is pretty much good to go! I'll be reviewing this ASAP!! |
I can't reference this directly as the code is a part of the |
This is a bit awkward to review since it is going to a branch that I can not review which needs a review. Is it at all possible if we just review the "gist" of this and then merge into that branch and then re-open |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would love to have made these all in line with the code but it just isn't possible with how the PR is laid out right now so I'll just list out blanket issues as I see them for now.
The biggest issue is the excessive use of String
and Vec<u8>
when parsing data, and the lack of size checks in a number of areas. Also, u128
is being used for balances but I believe these should be U256
.
DO NOTE: Some of the read_input()[..]
listed below are valid (though in hindsight you shouldn't need to add [..]
as just read_input()
is fine enough).
High priority
-
Issue with
EthConnectorContract::withdraw_near
. It reads the input asread_input()[..]
which alone isn't saying how many bytes the input should be, but also the fieldWithrdawlCallArgs.recepient_id
is aString
, which can be of any size. The problem is when we runvalidate_eth_address
with thatrecepient_id
is that there is anassert_eq!
which checks that thedata.len()
is20
. This is problematic as anyone with input can trip that assertion. There has to be a guarantee of size. -
Issue with
EthConnectorContract::deposit
. It takes theVec<u8>
raw_proof
and deserialises the data into aProof
but, there are now set data sizes, all fields areVec<u8>
meaning that anyone can make any of those fields any length. I would, if possible, set those sizes. Also, the deserialisation should be done in one step, not allVec<u8>
->Vec<u8>
snippets, then to otherStructs
. Should be done once to ensure the data parses correctly as soon as possible. -
Issue with
EthConnectorContract::finish_deposit_near
. Similar to above, when parsing the data, inFinishDepositCallArgs
,new_owner_id
,relayer_id
andproof_key
are all strings of no strict size. Further, there is no check to ensure that they are of the correct size. So, when you record the proof or mint near, these IDs look like they actually can end up being invalid. -
Issue with
EthConnectorContract::storage_deposit
, much like the others it reads an input of no discernable length. UsesAccountId
which is aString
with no set length. There also is no check to ensure that the length is correct in the inner methods. -
Issue with
FungibleToken::storage_withdraw
why is if there is a balance anything greater than 0 returns an error ofERR_WRONG_AMOUNT
? -
Issue with
EthConnectorContract::storage_balance_of
, again the issue of reading input of no discernable length being parsed into a String with no length check. At second glance theBalance
type, theu128
seems very wrong, shouldn't balance beU256
? -
Issue with
EthConnectContract::ft_on_transfer
, same issues as above,String
, no set size or checks. -
I do not agree that in
FungibleToken
the accounts should be stored as Strings. They should have to have a known size and be stored as bytes.
Medium priority
-
Lots of functional inconsistency in the library where most of the logic is handled not in the
contract
module. i.e, right now we havesdk::read_input()
being called in thecontract
module, but not in the methods themselves. Ideally, anything to do withsdk
should be somewhere else. See note below, as I'll probably tackle this. Also, likeEthConnectorContract::save_contract
should beset_contract
. There are a number of these. -
The errors that are returned via
expect
orunwrap
should be made into errors, thensdk_unwrap
ed orsdk_expect
ed. -
sdk::read_input()[..]
<-- generally you should explicitly state the start and end bytes. Though this isn't always the case as you can't possibly always know the length. -
The methods in
lib.rs
need to be sorted under the correct categories so that it's a bit more explicit which methods are mutative, and which are not. -
There are
assert_eq
everywhere, I think the sdk figure out where to spit them out... But not 100% sure. Reserve assertions for actual logic that is Fatal. -
A few errors don't follow the rest of the errors, like
ERR_TOPIC
, these need to be double-checked.
Low priority
-
A lot of the naming and style is quite inconsistent with the rest of the library but, I wouldn't mind tackling this in the future. e.g
EthConnectorContract::new
is a getter, not anew
. Also stuff likeinternal_unwrap_balance_of
should be something likeget_near_balance
/get_eth_balance
. If it's an actual internal method that is called by another layer, then it should be asinner_get_near_balance
. -
The design is quite fine, but there are a few things to note such as some methods that are associated with a
Struct
but don't use it. Those could exist outside of it. -
Pointless changes from
u128
toSting
then to&[u8]
inft_total_supply
ft_total_supply_near
ft_total_supply_eth
ft_balance_of
ft_balance_of_eth
. These can be directly changed into bytes. -
in
FungibleToken
there is an argregistration_only
that isn't used, this might be a TODO? It should be marked with_registration_only
and noted TODO explaining its purpose. The#[allow(unused_variables)]
should be dropped.
Notes
-
The use of
log
feature is great and should be replicated throughout the library. Obviously as another PR. -
The more that I look at everything, there should be a large refactor that would look like
Engine
wrapped bySdk
stuff, then it'll be easier to test the actual functional logic without actually needing the Near SDK. This desperately needs to be done and I'll tackle this as I got some notes on the matter already. -
I don't think that I could've possibly gone through everything with this pass, this PR is just so large with a lot of critical methods. If the above were fixed, I would do another pass.
-
I would love for a call to discuss the
deposit
methods as there is a bit of NEAR "magic" that I need to research on before I feel confident enough in how it works. In general it looks fine though.
use alloc::format; | ||
use alloc::string::{String, ToString}; | ||
use alloc::vec::Vec; | ||
use alloc::{ | ||
string::{String, ToString}, | ||
vec::Vec, | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These need to be all in the prelude.rs
for both std
and no_std
, and then import from there. There are a few other files like this too.
@joshuajbouw Great and very detailed review! I'll address some things that I'm aware of and that we already discussed with @mrLSD to speed up the process.
We should correspond the reference implementation of fungible token which uses
When we use
As already mentioned above,
This also matches the reference implementation. Though I'd say the returned error is not very clear and I suggest changing the description.
We don't have the
Already discussed it with @mrLSD internally but didn't post it there, sorry for that. We agreed that it's better to rename this to
For that purposes we have
I totally agree with you, but I think this was migrated (for consistency) from the reference implementation as well.
I didn't fully understand your mentioned idea here, so please explain in detail what do you meant. But as mentioned earlier, the regular Near SDK is not used here, rather just a minimal low-level implementation.
Sure, then let's schedule a call with @mrLSD. |
@joshuajbouw so for your comments that intersect the NEP-141 reference implementation, I suggest for us to keep the appropriate code unchanged and rather open some issues in the near-sdk-rs repository. |
@sept-en As I have noticed, right. When I have time, I'll give it a review and make notes and hopefully, some better practices can be put in place there. In the end, a |
@joshuajbouw I brought this up in a previous review as well. At that point it seemed like time pressures were such that it would not be addressed right away so I filed an issue: #28 If you work on factoring out |
@joshuajbouw thanks for yout deep diving response!
It's just
It's just panicked without any returns
What you mean |
Thanks for filing a new issue on that. Yeah, not required right now at all, just only concerned about the function of the PRs. |
@mrLSD thanks for the response. Yeah, @sept-en and I had a chat about it. I made the assumption that NEAR too the approach of others in that accounts were all bytes, and the TLD was a sort of layer on top of it, not actually the accounts themselves but it makes sense given you can associate private keys with a single TLD which is a good approach. Overall, given my history of working on other projects, that was a delight to find out. You can disregard my points on that. |
@artob @joshuajbouw notice it was added Diagram and Formal Spec in PR description. |
* Link to docs in the README. (#18) * Change deprecated `u64::max_value` to `u64::MAX`. (#38) * Support custom error messages. (#40) * Implement `begin_chain` for evm-bully. (#30) * Implement a faucet method. (#39) * Implement all Istanbul HF precompiles. (#21) * Check and increment nonces. (#42) * Fix the RIPEMD160 and ModExp precompiles. (#44) * Implement a first draft of `COINBASE` and `GASLIMIT`. (#47) * Refactor and improve error handling. (#49) * Replace `raw_call` with the new `submit` API. (#48) The `raw_call` method is hereby removed in favor of the new `submit` method that has an extended ABI capable of returning a transaction's revert status and logged events. Co-authored-by: Michael Birch <[email protected]> Co-authored-by: Arto Bendiken <[email protected]> * Add benchmarks for common EVM operations. (#41) * Merge branch 'master' into improved-evm-token-logic * Update error handling to `master` * fix missing import * cargo fmt * Ensure ETH transfers return an execution result. (#48) * Update to `master` * fix str types Co-authored-by: Frank Braun <[email protected]> Co-authored-by: Michael Birch <[email protected]> Co-authored-by: Arto Bendiken <[email protected]>
Co-authored-by: Joshua J. Bouw <[email protected]>
Co-authored-by: Joshua J. Bouw <[email protected]>
This aspect of things will need special attention from reviewers. Even if the EVM interface is specified as |
@mrLSD As discussed on our call just now, let's go ahead and merge this into |
THANKS! |
Changes related to new eth-connector design.
DIagram here
Formal specification