Skip to content
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

Identity transfer eth #145

Open
wants to merge 4 commits into
base: develop
Choose a base branch
from

Conversation

rdinicut
Copy link
Contributor

No description provided.

@rdinicut rdinicut requested review from lucasvo and xmxanuel April 11, 2019 18:43
* @param value uint256 wei supply for proxy execution
* @param data bytes ABI encoded call data
*/
function transferEth(
Copy link
Member

@xmxanuel xmxanuel Apr 12, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't we need a payable fallback function in the identity contract if we are dealing with ETH?

const numOfCalls = await this.testProxy.getCallsFrom(this.identity.address);
assert.equal(1, numOfCalls.toNumber());
})


it('should transferEth using the a identity ACTION key', async function () {
await this.identity.addKey(addressToBytes32(accounts[1]), ACTION, 1);
await shouldSucceed(this.identity.transferEth(accounts[2], 1, "0x1234", {from: accounts[1]}));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you check if account[2] has one more ETH on his account after the method call?

// solium-disable-next-line security/no-inline-assembly
assembly {
// check if contract to be call exists
// check if contract to be called exists
if iszero(extcodesize(to)) {
revert(0, 0)
}
success := call(gas, to, value, add(data, 0x20), mload(data), 0, 0)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens if the contract I want to send some ETH is not payable?

Would the complete transaction fail or would the identity contract own the money?

In case the identity contract would own it.
Is it possible to withdraw the ETH from the identity contract?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should know what contract you are calling. The identity contract is just a proxy and does not care about how the contract is calling is implemented. Funds on the identity contract is not something we support and I think it a broader discussion.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the whole transaction fails I am fine with it. :)

assembly {
// Make sure the address is not a contract
if gt(extcodesize(to),0) {
revert(0, 0)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not calling the execute method in that case?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do not understand you quesiton

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In case a user wants to send ETH to a contract. The user should use the execute method.

Suggested change
revert(0, 0)
success := execute(...)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok. but calling the execute method would result in the same line of code in the end:
success := call(gas, to, value, add(data, 0x20), mload(data), 0, 0)

Maybe I am questioning more the if condition itself :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because I want this method to revert and force the user to use the execute api. Execute is for contract call and transferEth is for account calling. The old execute method worked like this and the idea is to be more clear and have 2 methods.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The execute checkIfContract exists was a recommendation from ToB, if I am correct?
I don't want to change that.

In Ethereum accounts and contracts are on the same level. Let say I need to send ETH to a 1000 addresses, why should I care if the other users using an account or a contract.

Maybe I don't know it, and I would need to implement an additional check and switching between execute and transferETH for my 1000 transactions

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes that what you should do. You should know what addresses you are using. It the same thing if you send some Eth from metamask. The client should know if the address is correct and what is behind it. We could remove the check in the tranferEth and make it like the old execute method but then you could bypass execute and you are losing eth in the case you wanna call a contract and send it eth

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understood the Ethereum philosophy in that way: It shouldn't matter if an address is an account or a contract. This design decision enabled a lot of cool things like multi-sig contracts etc.

In case somebody would use our identity transferETH in another contract without an additional isContract check. It would suddenly matter if an address is an account or a contract.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Anyway, it is a more general discussion. Overall PR looks good. If a payable keyword is not needed and ETH is transferred.

/**
* @dev Throws if called by any account other than a ACTION key.
*/
modifier onlyAction() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

Copy link
Member

@xmxanuel xmxanuel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall LGTM.

I would recommend checking in tests the ETH balance of the accounts.


it('should transferEth using the a identity ACTION key', async function () {
await this.identity.addKey(addressToBytes32(accounts[1]), ACTION, 1);
await shouldSucceed(this.identity.transferEth(accounts[2], 1, "0x1234", {from: accounts[1]}));
await this.identity.addKey(addressToBytes32(accounts[2]), ACTION, 1);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@@ -66,6 +66,7 @@ contract Identity is KeyManager {
bytes memory data
) onlyAction
public
payable
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🥇

@xmxanuel
Copy link
Member

What about this PR?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants