diff --git a/src/base/orgs/Org.ts b/src/base/orgs/Org.ts index a0fd7ffbd..8b73d2505 100644 --- a/src/base/orgs/Org.ts +++ b/src/base/orgs/Org.ts @@ -132,6 +132,35 @@ export class Org { return org.setOwner(address); } + async setOwnerMultisig(owner: string, config: Config): Promise { + 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> { const safe = await utils.getSafe(this.owner, config); if (safe) { diff --git a/src/base/orgs/TransferOwnership.svelte b/src/base/orgs/TransferOwnership.svelte index 875bf5714..329f05560 100644 --- a/src/base/orgs/TransferOwnership.svelte +++ b/src/base/orgs/TransferOwnership.svelte @@ -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 {newOwner}. +
+ +
+ +{:else if state === State.Proposed && org} + +
+ 🪴 +
+ +
+

The transaction to set the owner of {formatAddress(org.address)} + to {newOwner} was proposed to:

+

+
+