fix: improvements in DsProxy execute (#177)

This commit is contained in:
Rohit Narurkar 2021-01-22 16:19:52 +05:30 committed by GitHub
parent 3105431007
commit 311884f076
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 18 additions and 26 deletions

View File

@ -40,15 +40,15 @@ const DS_PROXY_EXECUTE_CODE: &str =
/// let ds_proxy = DsProxy::new(ds_proxy_addr); /// let ds_proxy = DsProxy::new(ds_proxy_addr);
/// ///
/// // execute a transaction via the DsProxy instance. /// // execute a transaction via the DsProxy instance.
/// # let target_addr = Address::random(); /// let target = Address::random();
/// let target = AddressOrBytes::Address(target_addr);
/// let calldata: Bytes = vec![0u8; 32].into(); /// let calldata: Bytes = vec![0u8; 32].into();
/// let tx_hash = ds_proxy.execute::<HttpWallet, Arc<HttpWallet>>( /// let contract_call = ds_proxy.execute::<HttpWallet, Arc<HttpWallet>, Address>(
/// Arc::new(client), /// Arc::new(client),
/// target, /// target,
/// calldata, /// calldata,
/// ) /// )?;
/// .await?; /// let pending_tx = contract_call.send().await?;
/// let _tx_receipt = pending_tx.await?;
/// ///
/// # Ok(()) /// # Ok(())
/// # } /// # }
@ -146,36 +146,31 @@ impl DsProxy {
/// appropriate `execute` method is called, that is, either /// appropriate `execute` method is called, that is, either
/// [execute(address,bytes)](https://github.com/dapphub/ds-proxy/blob/master/src/proxy.sol#L53-L58) /// [execute(address,bytes)](https://github.com/dapphub/ds-proxy/blob/master/src/proxy.sol#L53-L58)
/// or [execute(bytes,bytes)](https://github.com/dapphub/ds-proxy/blob/master/src/proxy.sol#L39-L42). /// or [execute(bytes,bytes)](https://github.com/dapphub/ds-proxy/blob/master/src/proxy.sol#L39-L42).
pub async fn execute<M: Middleware, C: Into<Arc<M>>>( pub fn execute<M: Middleware, C: Into<Arc<M>>, T: Into<AddressOrBytes>>(
&self, &self,
client: C, client: C,
target: AddressOrBytes, target: T,
data: Bytes, data: Bytes,
) -> Result<TxHash, ContractError<M>> { ) -> Result<ContractCall<M, Bytes>, ContractError<M>> {
// construct the full contract using DsProxy's address and the injected client. // construct the full contract using DsProxy's address and the injected client.
let ds_proxy = self let ds_proxy = self
.contract .contract
.clone() .clone()
.into_contract(self.address, client.into()); .into_contract(self.address, client.into());
match target { match target.into() {
// handle the case when the target is an address to a deployed contract. // handle the case when the target is an address to a deployed contract.
AddressOrBytes::Address(addr) => { AddressOrBytes::Address(addr) => {
let selector = id("execute(address,bytes)"); let selector = id("execute(address,bytes)");
let args = (addr, data); let args = (addr, data);
let call: ContractCall<M, Bytes> = ds_proxy.method_hash(selector, args)?; Ok(ds_proxy.method_hash(selector, args)?)
let pending_tx = call.send().await?;
Ok(*pending_tx)
} }
// handle the case when the target is actually bytecode of a contract to be deployed // handle the case when the target is actually bytecode of a contract to be deployed
// and executed on. // and executed on.
AddressOrBytes::Bytes(code) => { AddressOrBytes::Bytes(code) => {
let selector = id("execute(bytes,bytes)"); let selector = id("execute(bytes,bytes)");
let args = (code, data); let args = (code, data);
let call: ContractCall<M, (Address, Bytes)> = Ok(ds_proxy.method_hash(selector, args)?)
ds_proxy.method_hash(selector, args)?;
let pending_tx = call.send().await?;
Ok(*pending_tx)
} }
} }
} }

View File

@ -7,7 +7,7 @@ use ethers_middleware::{
transformer::{DsProxy, TransformerMiddleware}, transformer::{DsProxy, TransformerMiddleware},
SignerMiddleware, SignerMiddleware,
}; };
use ethers_providers::{Http, Middleware, PendingTransaction, Provider}; use ethers_providers::{Http, Middleware, Provider};
use ethers_signers::LocalWallet; use ethers_signers::LocalWallet;
use rand::Rng; use rand::Rng;
use std::{convert::TryFrom, sync::Arc, time::Duration}; use std::{convert::TryFrom, sync::Arc, time::Duration};
@ -153,19 +153,16 @@ async fn ds_proxy_code() {
.expect("could not get ABI encoded data"); .expect("could not get ABI encoded data");
// execute code via the deployed DsProxy contract. // execute code via the deployed DsProxy contract.
let tx_hash = ds_proxy ds_proxy
.execute::<HttpWallet, Arc<HttpWallet>>( .execute::<HttpWallet, Arc<HttpWallet>, Bytes>(
Arc::clone(&provider), Arc::clone(&provider),
AddressOrBytes::Bytes(ss.bytecode.clone()), ss.bytecode.clone(),
calldata, calldata,
) )
.expect("could not construct DSProxy contract call")
.send()
.await .await
.expect("could not execute code via DSProxy"); .unwrap();
// wait for the tx to be confirmed.
PendingTransaction::new(tx_hash, provider.provider())
.await
.expect("could not confirm pending tx");
// verify that DsProxy's state was updated. // verify that DsProxy's state was updated.
let last_sender = provider let last_sender = provider