Add setOwner safe tx proposal creation

Signed-off-by: Sebastian Martinez <sebastinez@me.com>
This commit is contained in:
Sebastian Martinez
2021-11-25 15:11:54 +01:00
committed by Alexis Sellier
parent 7c3cfcac28
commit 6588ccafff
3 changed files with 74 additions and 7 deletions
+29
View File
@@ -132,6 +132,35 @@ export class Org {
return org.setOwner(address);
}
async setOwnerMultisig(owner: string, config: Config): Promise<void> {
assert(config.signer);
assert(config.safe.client);
const safeAddress = ethers.utils.getAddress(this.owner);
const orgAddress = ethers.utils.getAddress(this.address);
const org = new ethers.Contract(
this.address,
config.abi.org,
config.signer
);
const unsignedTx = await org.populateTransaction.setOwner(
owner
);
const txData = unsignedTx.data;
if (! txData) {
throw new Error("Org::setOwnerMultisig: Could not generate transaction for `setOwner` call");
}
const safeTx = {
to: orgAddress,
value: ethers.constants.Zero.toString(),
data: txData,
operation: OperationType.Call,
};
await utils.proposeSafeTransaction(safeTx, safeAddress, config);
}
async getMembers(config: Config): Promise<Array<string>> {
const safe = await utils.getSafe(this.owner, config);
if (safe) {
+43 -6
View File
@@ -5,6 +5,8 @@
import { formatAddress, isAddress } from "@app/utils";
import Loading from '@app/Loading.svelte';
import { assert } from '@app/error';
import * as utils from '@app/utils';
import Address from '@app/Address.svelte';
import type { Org } from './Org';
@@ -15,9 +17,16 @@
enum State {
Idle,
// Single sig states.
Signing,
Pending,
Success,
// Multi sig states.
Proposing,
Proposed,
Failed,
}
@@ -43,12 +52,18 @@
return;
}
state = State.Signing;
try {
let tx = await org.setOwner(newOwner, config);
state = State.Pending;
await tx.wait();
state = State.Success;
if (org && await utils.isSafe(org.owner, config)) {
state = State.Proposing;
await org.setOwnerMultisig(newOwner, config);
state = State.Proposed;
} else {
state = State.Signing;
let tx = await org.setOwner(newOwner, config);
state = State.Pending;
await tx.wait();
state = State.Success;
}
} catch (e) {
console.error(e);
state = State.Failed;
@@ -68,6 +83,24 @@
successfully transfered to <strong>{newOwner}</strong>.
</div>
<div slot="actions">
<button class="small" on:click={() => dispatch('close')}>
Done
</button>
</div>
</Modal>
{:else if state === State.Proposed && org}
<Modal floating>
<div slot="title">
🪴
</div>
<div slot="subtitle">
<p>The transaction to set the owner of <strong>{formatAddress(org.address)}</strong>
to <strong>{newOwner}</strong> was proposed to:</p>
<p><Address address={org.owner} {config} compact /></p>
</div>
<div slot="actions">
<button class="small" on:click={() => dispatch('close')}>
Done
@@ -86,6 +119,10 @@
Please confirm the transaction in your wallet.
{:else if state == State.Pending}
Waiting for transaction to be processed...
{:else if state == State.Proposing && org}
Proposal is being submitted to the safe
<strong>{formatAddress(org.owner)}</strong>,
please sign the transaction in your wallet.
{:else if state == State.Idle}
Transfer the ownership of Org <strong>{formatAddress(org.address)}</strong> to a new address.
{:else if state == State.Failed}
@@ -98,7 +135,7 @@
<div slot="body">
{#if state == State.Idle}
<input type="text" size="40" disabled={state !== State.Idle} bind:this={input} bind:value={newOwner} />
{:else if state == State.Pending || state == State.Signing}
{:else if state == State.Pending || state == State.Proposing || state == State.Signing}
<Loading small center />
{:else if state == State.Failed}
<!-- ... -->
+2 -1
View File
@@ -63,6 +63,7 @@
}
}
};
$: account = $session && $session.address;
$: isOwner = (org: Org): boolean => $session
? utils.isAddressEqual(org.owner, $session.address)
: false;
@@ -220,7 +221,7 @@
<div class="label">Owner</div>
<div><Address resolve {config} address={org.owner} /></div>
<div>
{#if isOwner(org)}
{#if isOwner(org) || (account && org.isMember(account, config))}
<button class="tiny secondary" on:click={transferOwnership}>
Transfer
</button>