Transaction

5A5CA0047AB43B…097A53608A58

Block 315,078 · index 1 · indexed

Summary

Hash
5A5CA0047AB43BF3AF605CC08DB43F667DADDF0AC50C3E21D042097A53608A58
Block
315,078
Size
49158 bytes
Gas used
67,724,515 / 110,000,000
Fee
220000ugnot
Status
success

Messages

#1AddPackagegno.land/r/samcrew/memba_dao24 arguments
Attached funds
28000000ugnot

Arguments · 24

  1. #1memba_dao
  2. #2appstore_adapter.gno
  3. #3package memba_dao import("strings";"gno.land/p/samcrew/memba_weighted_host";"gno.land/r/samcrew/memba_appstore_v3") func appstoreState(a memba_weighted_host.AppstoreAction)memba_weighted_host.AppstoreState{ owner:=memba_appstore_v3.GetOwner();s:=memba_weighted_host.AppstoreState{Owner:owner,PendingOwner:memba_appstore_v3.GetPendingOwner(),Treasury:memba_appstore_v3.GetTreasury(),Fee:memba_appstore_v3.GetRegistrationFee(),Paused:memba_appstore_v3.IsPaused(),Sealed:memba_appstore_v3.IsSeedingSealed(),OwnerCurator:memba_appstore_v3.IsCurator(string(owner)),DAOCurator:memba_appstore_v3.IsCurator(string(appstorePolicy.DAO())),SuccessorCurator:memba_appstore_v3.IsCurator(string(appstorePolicy.Successor()))} if a.Kind()==memba_weighted_host.AppstoreAddCurator||a.Kind()==memba_weighted_host.AppstoreRemoveCurator{s.SubjectCurator=memba_appstore_v3.IsCurator(string(a.Recipient()))} if a.IsListing(){l:=memba_appstore_v3.GetGovernanceListing(a.Path(),a.Kind()==memba_weighted_host.AppstoreClearFlags);s.Listing=memba_weighted_host.AppstoreListing{Exists:l.Exists,ContentHash:l.ContentHash,Status:l.Status,Reason:l.Reason,Credit:l.Credit,Flags:l.Flags,ClearKeys:l.ClearKeys}} return s } func proposeAppstore(cur realm,a memba_weighted_host.AppstoreAction)uint64{return host.ProposeAppstore(a,appstoreState(a),cur)} func ProposeAppstoreAccept(cur realm)uint64{return proposeAppstore(cur,appstorePolicy.Accept())} func ProposeAppstoreReturn(cur realm)uint64{return proposeAppstore(cur,appstorePolicy.Return())} func ProposeAppstoreAbortReturn(cur realm)uint64{return proposeAppstore(cur,appstorePolicy.AbortReturn())} func ProposeAppstoreTreasury(cur realm)uint64{return proposeAppstore(cur,appstorePolicy.SetTreasury())} func ProposeAppstoreFee(cur realm,fee int64)uint64{return proposeAppstore(cur,memba_weighted_host.AppstoreRegistrationFee(fee))} func ProposeAppstoreCurator(cur realm,who address,grant bool)uint64{return proposeAppstore(cur,memba_weighted_host.AppstoreCurator(who,grant))} func ProposeAppstoreUnpause(cur realm)uint64{return proposeAppstore(cur,memba_weighted_host.AppstoreResume())} func ProposeAppstoreSeal(cur realm)uint64{return proposeAppstore(cur,memba_weighted_host.AppstoreSealImport())} func ProposeAppstoreApprove(cur realm,path string)uint64{return proposeAppstore(cur,memba_weighted_host.AppstoreModeration(memba_weighted_host.AppstoreApprove,path,""))} func ProposeAppstoreReject(cur realm,path,reason string)uint64{return proposeAppstore(cur,memba_weighted_host.AppstoreModeration(memba_weighted_host.AppstoreReject,path,reason))} func ProposeAppstoreDelist(cur realm,path string)uint64{return proposeAppstore(cur,memba_weighted_host.AppstoreModeration(memba_weighted_host.AppstoreDelist,path,""))} func ProposeAppstoreRestore(cur realm,path string)uint64{return proposeAppstore(cur,memba_weighted_host.AppstoreModeration(memba_weighted_host.AppstoreRestore,path,""))} func ProposeAppstoreClearFlags(cur realm,path string)uint64{return proposeAppstore(cur,memba_weighted_host.AppstoreModeration(memba_weighted_host.AppstoreClearFlags,path,""))} func EmergencyPauseAppstore(cur realm){a:=memba_weighted_host.AppstoreResume();before:=appstoreState(a);host.PrepareAppstoreEmergencyPause(before,cur);expected:=before;expected.Paused=true;memba_appstore_v3.Pause(cross(cur),true);if appstoreState(a)!=expected{panic("appstore pause postcondition mismatch")}} func executeAppstore(cur realm,id uint64){ proposed:=host.Proposal(id).AppstoreAction;before:=appstoreState(proposed);a:=host.ConsumeAppstore(id,before,cur);expected:=before switch a.Kind(){ case memba_weighted_host.AppstoreAccept: expected.Owner=appstorePolicy.DAO();expected.PendingOwner="";expected.OwnerCurator=true;expected.DAOCurator=true;if before.Owner==appstorePolicy.Successor(){expected.SuccessorCurator=false};memba_appstore_v3.AcceptOwnership(cross(cur)) case memba_weighted_host.AppstoreReturn:expected.PendingOwner=a.Recipient();memba_appstore_v3.TransferOwnership(cross(cur),a.Recipient()) case memba_weighted_host.AppstoreAbortReturn:expected.PendingOwner="";memba_appstore_v3.CancelOwnershipTransfer(cross(cur)) case memba_weighted_host.AppstoreFee:expected.Fee=a.Fee();memba_appstore_v3.SetRegistrationFee(cross(cur),a.Fee()) case memba_weighted_host.AppstoreTreasury:expected.Treasury=a.Recipient();memba_appstore_v3.SetTreasury(cross(cur),a.Recipient()) case memba_weighted_host.AppstoreUnpause:expected.Paused=false;memba_appstore_v3.Pause(cross(cur),false) case memba_weighted_host.AppstoreSeal:expected.Sealed=true;memba_appstore_v3.FinalizeSeed(cross(cur)) case memba_weighted_host.AppstoreAddCurator,memba_weighted_host.AppstoreRemoveCurator: grant:=a.Kind()==memba_weighted_host.AppstoreAddCurator;expected.SubjectCurator=grant;if a.Recipient()==before.Owner{expected.OwnerCurator=grant};if a.Recipient()==appstorePolicy.DAO(){expected.DAOCurator=grant};if a.Recipient()==appstorePolicy.Successor(){expected.SuccessorCurator=grant};if grant{memba_appstore_v3.AddCurator(cross(cur),a.Recipient())}else{memba_appstore_v3.RemoveCurator(cross(cur),a.Recipient())} case memba_weighted_host.AppstoreApprove:expected.Listing.Status="live";memba_appstore_v3.ApproveApp(cross(cur),a.Path()) case memba_weighted_host.AppstoreReject:expected.Listing.Status="rejected";expected.Listing.Reason=a.Reason();expected.Listing.Credit=true;memba_appstore_v3.RejectApp(cross(cur),a.Path(),a.Reason()) case memba_weighted_host.AppstoreDelist:expected.Listing.Status="delisted";memba_appstore_v3.DelistApp(cross(cur),a.Path()) case memba_weighted_host.AppstoreRestore:expected.Listing.Status="pending";memba_appstore_v3.RestoreApp(cross(cur),a.Path()) case memba_weighted_host.AppstoreClearFlags: keys:=strings.Split(before.Listing.ClearKeys,",");if len(keys)>memba_appstore_v3.MaxClearBatch||len(keys)>before.Listing.Flags{panic("invalid appstore clear batch")};expected.Listing.Flags-=len(keys);expected.Listing.ClearKeys="" memba_appstore_v3.ClearFlags(cross(cur),a.Path()) for _,who:=range keys{if memba_appstore_v3.HasGovernanceFlag(a.Path(),who){panic("appstore clear dedupe postcondition mismatch")}} default:panic("unsupported appstore action") } after:=appstoreState(a);if a.Kind()==memba_weighted_host.AppstoreClearFlags{after.Listing.ClearKeys=""} if after!=expected{panic("appstore postcondition mismatch")} if a.Kind()==memba_weighted_host.AppstoreAccept&&memba_appstore_v3.IsCurator(string(before.Owner)){panic("appstore previous curator retained")} }
  4. #4arcade_adapter.gno
  5. #5// Fixed arcade dispatch; no score-writing, fee or arbitrary-call authority. package memba_dao import ( "gno.land/p/samcrew/memba_weighted_host" "gno.land/r/samcrew/memba_arcade_leaderboard_v1" ) func arcadeState(a memba_weighted_host.ArcadeAction)memba_weighted_host.ArcadeState{ owner:=memba_arcade_leaderboard_v1.GetOwner();subject:=false if a.Attester()!=""{subject=memba_arcade_leaderboard_v1.IsAttester(string(a.Attester()))} return memba_weighted_host.ArcadeState{Owner:owner,PendingOwner:memba_arcade_leaderboard_v1.GetPendingOwner(),Paused:memba_arcade_leaderboard_v1.IsPaused(),OwnerListed:memba_arcade_leaderboard_v1.IsAttester(string(owner)),DAOListed:memba_arcade_leaderboard_v1.IsAttester(string(arcadePolicy.DAO())),SuccessorListed:memba_arcade_leaderboard_v1.IsAttester(string(arcadePolicy.Successor())),SubjectListed:subject} } func ProposeArcadeAccept(cur realm)uint64{a:=arcadePolicy.Accept();return host.ProposeArcade(a,arcadeState(a),cur)} func ProposeArcadeReturn(cur realm)uint64{a:=arcadePolicy.Return();return host.ProposeArcade(a,arcadeState(a),cur)} func ProposeArcadeAbortReturn(cur realm)uint64{a:=arcadePolicy.AbortReturn();return host.ProposeArcade(a,arcadeState(a),cur)} func ProposeArcadeAddAttester(cur realm,who address)uint64{a:=arcadePolicy.AddAttester(who);return host.ProposeArcade(a,arcadeState(a),cur)} func ProposeArcadeRemoveAttester(cur realm,who address)uint64{a:=memba_weighted_host.ArcadeRevokeAttester(who);return host.ProposeArcade(a,arcadeState(a),cur)} func ProposeArcadeUnpause(cur realm)uint64{a:=memba_weighted_host.ArcadeResume();return host.ProposeArcade(a,arcadeState(a),cur)} func EmergencyPauseArcade(cur realm){ a:=memba_weighted_host.ArcadeResume();before:=arcadeState(a);host.PrepareArcadeEmergencyPause(before,cur);expected:=before;expected.Paused=true memba_arcade_leaderboard_v1.Pause(cross(cur),true) if arcadeState(a)!=expected{panic("arcade pause postcondition mismatch")} } func executeArcade(cur realm,id uint64){ proposed:=host.Proposal(id).ArcadeAction;before:=arcadeState(proposed);a:=host.ConsumeArcade(id,before,cur);expected:=before switch a.Kind(){ case memba_weighted_host.ArcadeAcceptOwner: expected.Owner=arcadePolicy.DAO();expected.PendingOwner="";expected.OwnerListed=before.DAOListed;memba_arcade_leaderboard_v1.AcceptOwnership(cross(cur)) case memba_weighted_host.ArcadeReturnOwner: expected.PendingOwner=a.Recipient();memba_arcade_leaderboard_v1.TransferOwnership(cross(cur),a.Recipient()) case memba_weighted_host.ArcadeAbortReturn: expected.PendingOwner="";memba_arcade_leaderboard_v1.CancelOwnershipTransfer(cross(cur)) case memba_weighted_host.ArcadeUnpause: expected.Paused=false;memba_arcade_leaderboard_v1.Pause(cross(cur),false) case memba_weighted_host.ArcadeAddAttester,memba_weighted_host.ArcadeRemoveAttester: listed:=a.Kind()==memba_weighted_host.ArcadeAddAttester;expected.SubjectListed=listed if a.Attester()==before.Owner{expected.OwnerListed=listed};if a.Attester()==arcadePolicy.DAO(){expected.DAOListed=listed};if a.Attester()==arcadePolicy.Successor(){expected.SuccessorListed=listed} if listed{memba_arcade_leaderboard_v1.AddAttester(cross(cur),a.Attester())}else{memba_arcade_leaderboard_v1.RemoveAttester(cross(cur),a.Attester())} default:panic("unsupported arcade action") } if arcadeState(a)!=expected{panic("arcade postcondition mismatch")} // Ownership operations preserve explicit appointments. IsAttester is the // allowlist bit; it is not the old owner's implicit authority. if a.Kind()==memba_weighted_host.ArcadeAcceptOwner && memba_arcade_leaderboard_v1.IsAttester(string(before.Owner))!=before.OwnerListed{panic("arcade old owner appointment changed")} }
  6. #6badges_adapter.gno
  7. #7// Fixed badges administration and authority return. Operational badge minting // remains with explicitly appointed admins; no arbitrary mint route is exposed. package memba_dao import ( "gno.land/p/samcrew/memba_weighted_host" "gno.land/r/samcrew/gnobuilders_badges_v2" ) func badgesState(a memba_weighted_host.BadgesAction) memba_weighted_host.BadgesState { owner := gnobuilders_badges_v2.GetOwner() subject := false if a.Subject() != "" { subject = gnobuilders_badges_v2.IsAdmin(a.Subject()) } return memba_weighted_host.BadgesState{ Owner: owner, PendingOwner: gnobuilders_badges_v2.GetPendingOwner(), Paused: gnobuilders_badges_v2.IsPaused(), AdminCount: gnobuilders_badges_v2.GetAdminCount(), OwnerAdmin: gnobuilders_badges_v2.IsAdmin(owner), DAOAdmin: gnobuilders_badges_v2.IsAdmin(badgesPolicy.DAO()), SuccessorAdmin: gnobuilders_badges_v2.IsAdmin(badgesPolicy.Successor()), SubjectAdmin: subject, } } func proposeBadges(cur realm, a memba_weighted_host.BadgesAction) uint64 { return host.ProposeBadges(a, badgesState(a), cur) } func ProposeBadgesAccept(cur realm) uint64 { return proposeBadges(cur, badgesPolicy.Accept()) } func ProposeBadgesReturn(cur realm) uint64 { return proposeBadges(cur, badgesPolicy.Return()) } func ProposeBadgesAbortReturn(cur realm) uint64 { return proposeBadges(cur, badgesPolicy.AbortReturn()) } func ProposeBadgesAddAdmin(cur realm, who address) uint64 { return proposeBadges(cur, badgesPolicy.AddAdmin(who)) } func ProposeBadgesRemoveAdmin(cur realm, who address) uint64 { return proposeBadges(cur, memba_weighted_host.BadgesRevokeAdmin(who)) } func ProposeBadgesUnpause(cur realm) uint64 { return proposeBadges(cur, memba_weighted_host.BadgesResume()) } func EmergencyPauseBadges(cur realm) { a := memba_weighted_host.BadgesResume() before := badgesState(a) host.PrepareBadgesEmergencyPause(before, cur) expected := before expected.Paused = true gnobuilders_badges_v2.Pause(cross(cur)) if badgesState(a) != expected { panic("badges pause postcondition mismatch") } } func executeBadges(cur realm, id uint64) { proposed := host.Proposal(id).BadgesAction before := badgesState(proposed) a := host.ConsumeBadges(id, before, cur) expected := before switch a.Kind() { case memba_weighted_host.BadgesAcceptOwner: expected.Owner = badgesPolicy.DAO() expected.PendingOwner = "" expected.OwnerAdmin = true expected.DAOAdmin = true if !before.DAOAdmin { expected.AdminCount++ } if before.OwnerAdmin { expected.AdminCount-- } if before.Owner == badgesPolicy.Successor() { expected.SuccessorAdmin = false } gnobuilders_badges_v2.AcceptOwnership(cross(cur)) case memba_weighted_host.BadgesReturnOwner: expected.PendingOwner = a.Recipient() gnobuilders_badges_v2.TransferOwnership(cross(cur), a.Recipient()) case memba_weighted_host.BadgesAbortReturn: expected.PendingOwner = "" gnobuilders_badges_v2.CancelOwnershipTransfer(cross(cur)) case memba_weighted_host.BadgesUnpause: expected.Paused = false gnobuilders_badges_v2.Unpause(cross(cur)) case memba_weighted_host.BadgesAddAdmin, memba_weighted_host.BadgesRemoveAdmin: grant := a.Kind() == memba_weighted_host.BadgesAddAdmin expected.SubjectAdmin = grant if grant { expected.AdminCount++ } else { expected.AdminCount-- } if a.Subject() == badgesPolicy.Successor() { expected.SuccessorAdmin = grant } if grant { gnobuilders_badges_v2.AddAdmin(cross(cur), a.Subject()) } else { gnobuilders_badges_v2.RemoveAdmin(cross(cur), a.Subject()) } default: panic("unsupported badges action") } if badgesState(a) != expected { panic("badges postcondition mismatch") } if a.Kind() == memba_weighted_host.BadgesAcceptOwner && gnobuilders_badges_v2.IsAdmin(before.Owner) { panic("badges previous owner admin retained") } }
  8. #8channels_adapter.gno
  9. #9// Fixed channels authority and membership. Content moderation remains with the // current owner and appointed target admins; votes cannot call arbitrary code. package memba_dao import ( "gno.land/p/samcrew/memba_weighted_host" channels "gno.land/r/samcrew/memba_dao_channels_v2" ) func channelsState(a memba_weighted_host.ChannelsAction) memba_weighted_host.ChannelsState { owner:=channels.GetOwner() subjectRoles:="" if a.Subject()!="" { subjectRoles=channels.GetMemberRoles(a.Subject()) } s:=memba_weighted_host.ChannelsState{ Owner:owner, PendingOwner:channels.GetPendingOwner(), Paused:channels.IsPaused(), MemberCount:channels.GetMemberCount(), MembershipRevision:channels.GetMembershipRevision(), OwnerRoles:channels.GetMemberRoles(owner), OwnerMember:channels.IsMember(owner), DAOMember:channels.IsMember(channelsPolicy.DAO()), SuccessorMember:channels.IsMember(channelsPolicy.Successor()), SubjectMember:a.Subject()!="" && channels.IsMember(a.Subject()), DAORoles:channels.GetMemberRoles(channelsPolicy.DAO()), SuccessorRoles:channels.GetMemberRoles(channelsPolicy.Successor()), SubjectRoles:subjectRoles, } s.ChannelCount,s.ChannelExists,s.ChannelDescription,s.ChannelType,s.ChannelReadRoles,s.ChannelWriteRoles=channels.GetChannelState(a.Name()) return s } func proposeChannels(cur realm,a memba_weighted_host.ChannelsAction) uint64 { return host.ProposeChannels(a,channelsState(a),cur) } func ProposeChannelsAccept(cur realm) uint64 { return proposeChannels(cur,channelsPolicy.Accept()) } func ProposeChannelsReturn(cur realm) uint64 { return proposeChannels(cur,channelsPolicy.Return()) } func ProposeChannelsAbortReturn(cur realm) uint64 { return proposeChannels(cur,channelsPolicy.AbortReturn()) } func ProposeChannelsAddMember(cur realm,who address,roles string) uint64 { return proposeChannels(cur,channelsPolicy.AddMember(who,roles)) } func ProposeChannelsRemoveMember(cur realm,who address) uint64 { return proposeChannels(cur,channelsPolicy.RemoveMember(who)) } func ProposeChannelsSetRoles(cur realm,who address,roles string) uint64 { return proposeChannels(cur,channelsPolicy.SetRoles(who,roles)) } func ProposeChannelsCreateText(cur realm,name,description string) uint64 { return proposeChannels(cur,channelsPolicy.CreateText(name,description)) } func ProposeChannelsUnpause(cur realm) uint64 { return proposeChannels(cur,memba_weighted_host.ChannelsResume()) } func EmergencyPauseChannels(cur realm) { a:=memba_weighted_host.ChannelsResume() before:=channelsState(a) host.PrepareChannelsEmergencyPause(before,cur) expected:=before; expected.Paused=true channels.PauseRealm(cross(cur)) if channelsState(a)!=expected { panic("channels pause postcondition mismatch") } } func executeChannels(cur realm,id uint64) { proposed:=host.Proposal(id).ChannelsAction before:=channelsState(proposed) a:=host.ConsumeChannels(id,before,cur) expected:=before switch a.Kind() { case memba_weighted_host.ChannelsAcceptOwner: expected.Owner=channelsPolicy.DAO();expected.PendingOwner="" expected.OwnerRoles="admin";expected.DAORoles="admin";expected.OwnerMember=true;expected.DAOMember=true expected.MembershipRevision++ if before.Owner==channelsPolicy.Successor() { expected.SuccessorRoles="";expected.SuccessorMember=false } channels.AcceptOwnership(cross(cur)) case memba_weighted_host.ChannelsReturnOwner: expected.PendingOwner=a.Recipient() channels.ProposeOwner(cross(cur),a.Recipient()) case memba_weighted_host.ChannelsAbortReturn: expected.PendingOwner="" channels.CancelPendingOwner(cross(cur)) case memba_weighted_host.ChannelsAddMember: expected.MemberCount++;expected.MembershipRevision++;expected.SubjectRoles=a.Roles();expected.SubjectMember=true channels.AddMember(cross(cur),a.Subject(),a.Roles()) case memba_weighted_host.ChannelsRemoveMember: expected.MemberCount--;expected.MembershipRevision++;expected.SubjectRoles="";expected.SubjectMember=false if a.Subject()==channelsPolicy.Successor() { expected.SuccessorRoles="";expected.SuccessorMember=false } channels.RemoveMember(cross(cur),a.Subject()) case memba_weighted_host.ChannelsSetRoles: expected.MembershipRevision++;expected.SubjectRoles=a.Roles() channels.UpdateMemberRoles(cross(cur),a.Subject(),a.Roles()) case memba_weighted_host.ChannelsCreateText: expected.ChannelCount++;expected.ChannelExists=true expected.ChannelDescription=a.Description();expected.ChannelType="text" expected.ChannelReadRoles="admin,dev,ops,member";expected.ChannelWriteRoles="admin,dev,ops,member" channels.CreateChannel(cross(cur),a.Name(),a.Description(),"text") case memba_weighted_host.ChannelsUnpause: expected.Paused=false channels.UnpauseRealm(cross(cur)) default: panic("unsupported channels action") } if channelsState(a)!=expected { panic("channels postcondition mismatch") } if a.Kind()==memba_weighted_host.ChannelsAcceptOwner && channels.IsMember(before.Owner) { panic("channels previous owner membership retained") } }
  10. #10escrow_adapter.gno
  11. #11package memba_dao import("chain";"chain/banker";"chain/runtime";"gno.land/p/samcrew/memba_weighted_host";"gno.land/r/samcrew/escrow_v4") func escrowState(a memba_weighted_host.EscrowAction)memba_weighted_host.EscrowState{ p:=escrow_v4.PauseState();if p.Paused!=escrow_v4.IsPaused(){panic("invalid escrow pause read")} s:=memba_weighted_host.EscrowState{Owner:address(escrow_v4.GetAdmin()),PendingOwner:address(escrow_v4.GetPendingAdmin()),FeeRecipient:address(escrow_v4.GetFeeRecipient()),PendingFeeRecipient:address(escrow_v4.GetPendingFeeRecipient()),Paused:p.Paused,PausedAt:p.PausedAt,ExitsReopenAt:p.ExitsReopenAt,CooldownUntil:p.CooldownUntil,ExitsOpen:p.ExitsOpen} if a.IsResolution(){ c:=escrow_v4.GetGovernanceContract(a.ContractID());s.Contract=memba_weighted_host.EscrowContract{Exists:c.Exists,ID:c.ID,ContentHash:c.ContentHash,Status:c.Status,Client:c.Client,Freelancer:c.Freelancer,Count:c.Count} for i,m:=range c.Milestones{s.Contract.Milestones[i]=memba_weighted_host.EscrowMilestone{ID:m.ID,Amount:m.Amount,Status:m.Status,FundedAt:m.FundedAt,CompletedAt:m.CompletedAt,DisputedAt:m.DisputedAt,PreDisputeStatus:m.PreDisputeStatus}} } if a.Kind()==memba_weighted_host.EscrowPayFreelancer{f:=escrow_v4.GetGovernanceFeeTerms();s.Fees=memba_weighted_host.EscrowFeeTerms{RawBPS:f.RawBPS,EffectiveBPS:f.EffectiveBPS,RawTreasury:f.RawTreasury,FallbackTreasury:f.FallbackTreasury,EffectiveTreasury:f.EffectiveTreasury}} return s } func proposeEscrow(cur realm,a memba_weighted_host.EscrowAction)uint64{return host.ProposeEscrow(a,escrowState(a),cur)} func ProposeEscrowAccept(cur realm)uint64{return proposeEscrow(cur,escrowPolicy.Accept())} func ProposeEscrowReturn(cur realm)uint64{return proposeEscrow(cur,escrowPolicy.Return())} func ProposeEscrowAbortReturn(cur realm)uint64{return proposeEscrow(cur,escrowPolicy.AbortReturn())} func ProposeEscrowUnpause(cur realm)uint64{return proposeEscrow(cur,memba_weighted_host.EscrowResume())} func ProposeEscrowRefund(cur realm,id string,index int)uint64{return proposeEscrow(cur,memba_weighted_host.EscrowResolution(id,index,true))} func ProposeEscrowPayFreelancer(cur realm,id string,index int)uint64{return proposeEscrow(cur,memba_weighted_host.EscrowResolution(id,index,false))} // ProposeEscrowFeeRecipient stages recipient as the fallback fee recipient; // recipient then accepts on escrow_v4 with its own AcceptFeeRecipient call. func ProposeEscrowFeeRecipient(cur realm,recipient address)uint64{return proposeEscrow(cur,memba_weighted_host.EscrowFeeRecipient(recipient))} func EmergencyPauseEscrow(cur realm){a:=memba_weighted_host.EscrowResume();before:=escrowState(a);host.PrepareEscrowEmergencyPause(before,cur);h:=runtime.ChainHeight();expected:=before;expected.Paused=true;expected.PausedAt=h;expected.ExitsReopenAt=h+escrow_v4.MaxPauseBlks;expected.ExitsOpen=false;escrow_v4.Pause(cross(cur));if escrowState(a)!=expected{panic("escrow pause postcondition mismatch")}} type escrowBalance struct{who address;before,delta,want int64} func escrowCredit(rows []escrowBalance,who address,amount int64)[]escrowBalance{ if amount==0{return rows};if amount<0||!who.IsValid(){panic("invalid escrow credit")} if who==escrowPolicy.DAO()||who==chain.PackageAddress(memba_weighted_host.EscrowPath){panic("escrow payout cannot be trapped in governance or escrow")} for i:=range rows{if rows[i].who==who{rows[i].delta+=amount;return rows}} return append(rows,escrowBalance{who:who,delta:amount}) } // Global solvency is checked at execution, not frozen at proposal creation: // unrelated funding or dust may arrive while members vote. Aggregate aliases. func escrowSettlement(a memba_weighted_host.EscrowAction,s memba_weighted_host.EscrowState)([]escrowBalance,int64){ realmAddr:=chain.PackageAddress(memba_weighted_host.EscrowPath);amount:=s.Contract.Milestones[a.Milestone()].Amount liable:=escrow_v4.TotalLiabilities();bnk:=banker.NewReadonlyBanker() if amount<=0||liable<amount||bnk.GetCoin(realmAddr,"ugnot")<liable{panic("escrow is not solvent")} rows:=[]escrowBalance{{who:realmAddr,delta:-amount}} if a.Kind()==memba_weighted_host.EscrowRefundClient{rows=escrowCredit(rows,s.Contract.Client,amount)}else{ bps:=s.Fees.EffectiveBPS;if bps<0||bps>500{panic("invalid escrow payout terms")} fee:=(amount/10000)*bps+((amount%10000)*bps)/10000 rows=escrowCredit(rows,s.Contract.Freelancer,amount-fee);rows=escrowCredit(rows,s.Fees.EffectiveTreasury,fee) } for i:=range rows{ r:=&rows[i];r.before=bnk.GetCoin(r.who,"ugnot") if r.before<0||(r.delta<0&&r.before< -r.delta)||(r.delta>0&&r.before>9223372036854775807-r.delta){panic("invalid escrow balance delta")} r.want=r.before+r.delta } return rows,liable-amount } func executeEscrow(cur realm,id uint64){ proposed:=host.Proposal(id).EscrowAction;before:=escrowState(proposed);var balances []escrowBalance;var liabilityAfter int64 if proposed.IsResolution(){balances,liabilityAfter=escrowSettlement(proposed,before)} a:=host.ConsumeEscrow(id,before,cur);expected:=before switch a.Kind(){ case memba_weighted_host.EscrowAcceptOwner:expected.Owner=escrowPolicy.DAO();expected.PendingOwner="";escrow_v4.AcceptOwnership(cross(cur)) case memba_weighted_host.EscrowReturnOwner:expected.PendingOwner=a.Recipient();escrow_v4.TransferOwnership(cross(cur),a.Recipient()) case memba_weighted_host.EscrowAbortReturn:expected.PendingOwner="";escrow_v4.CancelOwnershipTransfer(cross(cur)) case memba_weighted_host.EscrowUnpause:expected.Paused=false;expected.PausedAt=0;expected.ExitsReopenAt=0;expected.ExitsOpen=true;expected.CooldownUntil=runtime.ChainHeight()+escrow_v4.PauseCooldownBlks;escrow_v4.Unpause(cross(cur)) case memba_weighted_host.EscrowSetFeeRecipient:expected.PendingFeeRecipient=a.Recipient();escrow_v4.ProposeFeeRecipient(cross(cur),a.Recipient()) case memba_weighted_host.EscrowRefundClient,memba_weighted_host.EscrowPayFreelancer: refund:=a.Kind()==memba_weighted_host.EscrowRefundClient expected.Contract.Milestones[a.Milestone()].Status="released";if refund{expected.Contract.Milestones[a.Milestone()].Status="refunded"} // escrow_v4 settles the contract once every milestone is released or // refunded: completed if all were released, cancelled otherwise. expected.Contract.Status="active";allReleased,allTerminal:=true,true for i:=0;i<expected.Contract.Count;i++{m:=expected.Contract.Milestones[i];if m.Status=="disputed"{expected.Contract.Status="disputed"};if m.Status!="released"{allReleased=false};if m.Status!="released"&&m.Status!="refunded"{allTerminal=false}} if allTerminal{expected.Contract.Status="cancelled";if allReleased{expected.Contract.Status="completed"}} escrow_v4.ResolveDispute(cross(cur),a.ContractID(),a.Milestone(),refund) default:panic("unsupported escrow action") } if escrowState(a)!=expected{panic("escrow postcondition mismatch")} if a.IsResolution(){ if escrow_v4.TotalLiabilities()!=liabilityAfter{panic("escrow liability postcondition mismatch")} bnk:=banker.NewReadonlyBanker();for _,r:=range balances{if bnk.GetCoin(r.who,"ugnot")!=r.want{panic("escrow balance postcondition mismatch")}} if bnk.GetCoin(chain.PackageAddress(memba_weighted_host.EscrowPath),"ugnot")<liabilityAfter{panic("escrow solvency postcondition mismatch")} } }
  12. #12feed_adapter.gno
  13. #13// Fixed feed authority and moderator appointment. Content moderation stays // with the current owner or explicitly appointed moderators. package memba_dao import ( "gno.land/p/samcrew/memba_weighted_host" "gno.land/r/samcrew/memba_feed_v1" ) func feedState(a memba_weighted_host.FeedAction) memba_weighted_host.FeedState { owner := memba_feed_v1.GetOwner() subject := false if a.Subject() != "" { subject = memba_feed_v1.IsModerator(a.Subject()) } return memba_weighted_host.FeedState{ Owner: owner, PendingOwner: memba_feed_v1.GetPendingOwner(), Paused: memba_feed_v1.IsPaused(), ModeratorCount: memba_feed_v1.GetModeratorCount(), OwnerModerator: memba_feed_v1.IsModerator(owner), DAOModerator: memba_feed_v1.IsModerator(feedPolicy.DAO()), SuccessorModerator: memba_feed_v1.IsModerator(feedPolicy.Successor()), SubjectModerator: subject, } } func proposeFeed(cur realm, a memba_weighted_host.FeedAction) uint64 { return host.ProposeFeed(a, feedState(a), cur) } func ProposeFeedAccept(cur realm) uint64 { return proposeFeed(cur, feedPolicy.Accept()) } func ProposeFeedReturn(cur realm) uint64 { return proposeFeed(cur, feedPolicy.Return()) } func ProposeFeedAbortReturn(cur realm) uint64 { return proposeFeed(cur, feedPolicy.AbortReturn()) } func ProposeFeedAddModerator(cur realm, who address) uint64 { return proposeFeed(cur, feedPolicy.AddModerator(who)) } func ProposeFeedRemoveModerator(cur realm, who address) uint64 { return proposeFeed(cur, memba_weighted_host.FeedRevokeModerator(who)) } func ProposeFeedUnpause(cur realm) uint64 { return proposeFeed(cur, memba_weighted_host.FeedResume()) } func EmergencyPauseFeed(cur realm) { a := memba_weighted_host.FeedResume() before := feedState(a) host.PrepareFeedEmergencyPause(before, cur) expected := before expected.Paused = true memba_feed_v1.PauseRealm(cross(cur)) if feedState(a) != expected { panic("feed pause postcondition mismatch") } } func executeFeed(cur realm, id uint64) { proposed := host.Proposal(id).FeedAction before := feedState(proposed) a := host.ConsumeFeed(id, before, cur) expected := before switch a.Kind() { case memba_weighted_host.FeedAcceptOwner: expected.Owner = feedPolicy.DAO() expected.PendingOwner = "" expected.OwnerModerator = before.DAOModerator memba_feed_v1.AcceptOwnership(cross(cur)) case memba_weighted_host.FeedReturnOwner: expected.PendingOwner = a.Recipient() memba_feed_v1.TransferOwnership(cross(cur), a.Recipient()) case memba_weighted_host.FeedAbortReturn: expected.PendingOwner = "" memba_feed_v1.CancelOwnershipTransfer(cross(cur)) case memba_weighted_host.FeedUnpause: expected.Paused = false memba_feed_v1.UnpauseRealm(cross(cur)) case memba_weighted_host.FeedAddModerator, memba_weighted_host.FeedRemoveModerator: grant := a.Kind() == memba_weighted_host.FeedAddModerator expected.SubjectModerator = grant if grant { expected.ModeratorCount++ } else { expected.ModeratorCount-- } if a.Subject() == feedPolicy.Successor() { expected.SuccessorModerator = grant } if a.Subject() == feedPolicy.DAO() { expected.DAOModerator = grant; expected.OwnerModerator = grant } if grant { memba_feed_v1.AddModerator(cross(cur), a.Subject()) } else { memba_feed_v1.RemoveModerator(cross(cur), a.Subject()) } default: panic("unsupported feed action") } if feedState(a) != expected { panic("feed postcondition mismatch") } if a.Kind() == memba_weighted_host.FeedAcceptOwner && memba_feed_v1.IsModerator(before.Owner) { panic("feed previous owner moderator retained") } }
  14. #14feedback_adapter.gno
  15. #15// Fixed feedback authority and membership. Content moderation remains with the // current owner and appointed target admins; votes cannot call arbitrary code. package memba_dao import ( "gno.land/p/samcrew/memba_weighted_host" feedback "gno.land/r/samcrew/memba_feedback_v2" ) func feedbackState(a memba_weighted_host.FeedbackAction) memba_weighted_host.FeedbackState { owner:=feedback.GetOwner() subjectRoles:="" if a.Subject()!="" { subjectRoles=feedback.GetMemberRoles(a.Subject()) } s:=memba_weighted_host.FeedbackState{ Owner:owner, PendingOwner:feedback.GetPendingOwner(), Paused:feedback.IsPaused(), MemberCount:feedback.GetMemberCount(), MembershipRevision:feedback.GetMembershipRevision(), OwnerRoles:feedback.GetMemberRoles(owner), OwnerMember:feedback.IsMember(owner), DAOMember:feedback.IsMember(feedbackPolicy.DAO()), SuccessorMember:feedback.IsMember(feedbackPolicy.Successor()), SubjectMember:a.Subject()!="" && feedback.IsMember(a.Subject()), DAORoles:feedback.GetMemberRoles(feedbackPolicy.DAO()), SuccessorRoles:feedback.GetMemberRoles(feedbackPolicy.Successor()), SubjectRoles:subjectRoles, } s.ChannelCount,s.ChannelExists,s.ChannelDescription,s.ChannelType,s.ChannelReadRoles,s.ChannelWriteRoles=feedback.GetChannelState(a.Name()) return s } func proposeFeedback(cur realm,a memba_weighted_host.FeedbackAction) uint64 { return host.ProposeFeedback(a,feedbackState(a),cur) } func ProposeFeedbackAccept(cur realm) uint64 { return proposeFeedback(cur,feedbackPolicy.Accept()) } func ProposeFeedbackReturn(cur realm) uint64 { return proposeFeedback(cur,feedbackPolicy.Return()) } func ProposeFeedbackAbortReturn(cur realm) uint64 { return proposeFeedback(cur,feedbackPolicy.AbortReturn()) } func ProposeFeedbackAddMember(cur realm,who address,roles string) uint64 { return proposeFeedback(cur,feedbackPolicy.AddMember(who,roles)) } func ProposeFeedbackRemoveMember(cur realm,who address) uint64 { return proposeFeedback(cur,feedbackPolicy.RemoveMember(who)) } func ProposeFeedbackSetRoles(cur realm,who address,roles string) uint64 { return proposeFeedback(cur,feedbackPolicy.SetRoles(who,roles)) } func ProposeFeedbackCreateText(cur realm,name,description string) uint64 { return proposeFeedback(cur,feedbackPolicy.CreateText(name,description)) } func ProposeFeedbackUnpause(cur realm) uint64 { return proposeFeedback(cur,memba_weighted_host.FeedbackResume()) } func EmergencyPauseFeedback(cur realm) { a:=memba_weighted_host.FeedbackResume() before:=feedbackState(a) host.PrepareFeedbackEmergencyPause(before,cur) expected:=before; expected.Paused=true feedback.PauseRealm(cross(cur)) if feedbackState(a)!=expected { panic("feedback pause postcondition mismatch") } } func executeFeedback(cur realm,id uint64) { proposed:=host.Proposal(id).FeedbackAction before:=feedbackState(proposed) a:=host.ConsumeFeedback(id,before,cur) expected:=before switch a.Kind() { case memba_weighted_host.FeedbackAcceptOwner: expected.Owner=feedbackPolicy.DAO();expected.PendingOwner="" expected.OwnerRoles="admin";expected.DAORoles="admin";expected.OwnerMember=true;expected.DAOMember=true expected.MemberCount++;expected.MembershipRevision++ expected.SuccessorRoles="member";expected.SuccessorMember=true feedback.AcceptOwnership(cross(cur)) case memba_weighted_host.FeedbackReturnOwner: expected.PendingOwner=a.Recipient() feedback.TransferOwnership(cross(cur),a.Recipient()) case memba_weighted_host.FeedbackAbortReturn: expected.PendingOwner="" feedback.CancelOwnershipTransfer(cross(cur)) case memba_weighted_host.FeedbackAddMember: expected.MemberCount++;expected.MembershipRevision++;expected.SubjectRoles=a.Roles();expected.SubjectMember=true feedback.AddMember(cross(cur),a.Subject(),a.Roles()) case memba_weighted_host.FeedbackRemoveMember: expected.MemberCount--;expected.MembershipRevision++;expected.SubjectRoles="";expected.SubjectMember=false if a.Subject()==feedbackPolicy.Successor() { expected.SuccessorRoles="";expected.SuccessorMember=false } feedback.RemoveMember(cross(cur),a.Subject()) case memba_weighted_host.FeedbackSetRoles: expected.MembershipRevision++;expected.SubjectRoles=a.Roles() feedback.UpdateMemberRoles(cross(cur),a.Subject(),a.Roles()) case memba_weighted_host.FeedbackCreateText: expected.ChannelCount++;expected.ChannelExists=true expected.ChannelDescription=a.Description();expected.ChannelType="text" expected.ChannelReadRoles="admin,dev,ops,member";expected.ChannelWriteRoles="admin,dev,ops,member" feedback.CreateChannel(cross(cur),a.Name(),a.Description(),"text") case memba_weighted_host.FeedbackUnpause: expected.Paused=false feedback.UnpauseRealm(cross(cur)) default: panic("unsupported feedback action") } if feedbackState(a)!=expected { panic("feedback postcondition mismatch") } if a.Kind()==memba_weighted_host.FeedbackAcceptOwner && feedback.GetMemberRoles(before.Owner)!="member" { panic("feedback previous owner admin retained") } }
  16. #16gnomod.toml
  17. #17module = "gno.land/r/samcrew/memba_dao" gno = "0.9"
  18. #18market_adapter.gno
  19. #19// Fixed-target adapter. No callback, arbitrary call, or recovered panic path. package memba_dao import ( "gno.land/p/samcrew/memba_weighted_host" "gno.land/r/samcrew/memba_market_config" ) func marketState(a memba_weighted_host.MarketAction) memba_weighted_host.MarketState { bps := int64(0) if a.Kind() == memba_weighted_host.MarketSetFee { bps = int64(memba_market_config.GetFeeBPS(string(a.Lane()))) } return memba_weighted_host.MarketState{Admin: memba_market_config.GetAdmin(), PendingAdmin: memba_market_config.GetPendingAdmin(), Treasury: memba_market_config.GetTreasury(), BPS: bps} } func ProposeMarketAccept(cur realm) uint64 { a := memba_weighted_host.MarketAccept() return host.ProposeMarket(a, marketState(a), cur) } func ProposeMarketFee(cur realm, lane string, bps int64) uint64 { a := memba_weighted_host.MarketFee(memba_weighted_host.MarketLane(lane), bps) return host.ProposeMarket(a, marketState(a), cur) } func ProposeMarketTreasury(cur realm) uint64 { a := marketPolicy.SetTreasury() return host.ProposeMarket(a, marketState(a), cur) } func ProposeMarketReturn(cur realm) uint64 { a := marketPolicy.ReturnAdmin() return host.ProposeMarket(a, marketState(a), cur) } func ProposeMarketAbortReturn(cur realm) uint64 { a := marketPolicy.AbortReturn() return host.ProposeMarket(a, marketState(a), cur) } func executeMarket(cur realm, id uint64) { proposed := host.Proposal(id).MarketAction before := marketState(proposed) a := host.ConsumeMarket(id, before, cur) expected := before switch a.Kind() { case memba_weighted_host.MarketAcceptAdmin: expected.Admin = marketPolicy.DAO() expected.PendingAdmin = "" memba_market_config.AcceptAdmin(cross(cur)) case memba_weighted_host.MarketSetFee: expected.BPS = a.BPS() memba_market_config.SetFeeBPS(cross(cur), string(a.Lane()), a.BPS()) case memba_weighted_host.MarketSetTreasury: expected.Treasury = a.Recipient() memba_market_config.SetTreasury(cross(cur), a.Recipient()) case memba_weighted_host.MarketReturnAdmin: expected.PendingAdmin = a.Recipient() memba_market_config.TransferAdmin(cross(cur), a.Recipient()) case memba_weighted_host.MarketAbortReturn: expected.PendingAdmin = "" memba_market_config.CancelAdminTransfer(cross(cur)) default: panic("unsupported market action") } // Stage-return deliberately retains DAO admin until the successor accepts // separately. A mismatch aborts the entire transaction, including Consume. if marketState(a) != expected { panic("market postcondition mismatch") } }
  20. #20memba_dao.gno
  21. #21// Founding Memba DAO candidate. Initial roles follow the approved policy. // Keep the host private. This realm supports governed role changes, same-person key recovery and the fixed application adapters named in Render. package memba_dao import ( "chain" "gno.land/p/samcrew/memba_weighted_host" "gno.land/p/samcrew/memba_weighted_policy" ) var host *memba_weighted_host.Host var feedbackPolicy = memba_weighted_host.NewFeedbackPolicy(chain.PackageAddress("gno.land/r/samcrew/memba_dao"), "g136j0m08pkm2lwwde9dmlx8uee26llent9s5cpf") var channelsPolicy = memba_weighted_host.NewChannelsPolicy(chain.PackageAddress("gno.land/r/samcrew/memba_dao"), "g136j0m08pkm2lwwde9dmlx8uee26llent9s5cpf") var feedPolicy = memba_weighted_host.NewFeedPolicy(chain.PackageAddress("gno.land/r/samcrew/memba_dao"), "g136j0m08pkm2lwwde9dmlx8uee26llent9s5cpf") var badgesPolicy = memba_weighted_host.NewBadgesPolicy(chain.PackageAddress("gno.land/r/samcrew/memba_dao"), "g136j0m08pkm2lwwde9dmlx8uee26llent9s5cpf") var escrowPolicy = memba_weighted_host.NewEscrowPolicy(chain.PackageAddress("gno.land/r/samcrew/memba_dao"), "g136j0m08pkm2lwwde9dmlx8uee26llent9s5cpf") var appstorePolicy = memba_weighted_host.NewAppstorePolicy(chain.PackageAddress("gno.land/r/samcrew/memba_dao"), "g136j0m08pkm2lwwde9dmlx8uee26llent9s5cpf", "g1jw76lxvzjafw2kyjhdnzwggcftyhnlfjaer2u0") var arcadePolicy = memba_weighted_host.NewArcadePolicy(chain.PackageAddress("gno.land/r/samcrew/memba_dao"), "g136j0m08pkm2lwwde9dmlx8uee26llent9s5cpf") var questPolicy = memba_weighted_host.NewQuestPolicy(chain.PackageAddress("gno.land/r/samcrew/memba_dao"), "g136j0m08pkm2lwwde9dmlx8uee26llent9s5cpf") var reviewsPolicy = memba_weighted_host.NewReviewsPolicy(chain.PackageAddress("gno.land/r/samcrew/memba_dao"), "gno.land/r/samcrew/memba_reviews_v2", "g136j0m08pkm2lwwde9dmlx8uee26llent9s5cpf") var marketPolicy = memba_weighted_host.NewMarketPolicy(chain.PackageAddress("gno.land/r/samcrew/memba_dao"), "g1jw76lxvzjafw2kyjhdnzwggcftyhnlfjaer2u0", "g136j0m08pkm2lwwde9dmlx8uee26llent9s5cpf") func init(cur realm) { host = memba_weighted_host.NewWithApplications([]memba_weighted_host.Seat{ {Member: memba_weighted_policy.Member{PersonID: "zxxma", Address: "g1747t5m2f08plqjlrjk2q0qld7465hxz8gkx59c", Founder: true}, Admin: true, Finance: true}, {Member: memba_weighted_policy.Member{PersonID: "mikael", Address: "g1lyejwwmxef5tn8nx69saykmgm8rlr4xq9yeh3z", Founder: false}, Admin: false, Finance: false}, {Member: memba_weighted_policy.Member{PersonID: "ghost", Address: "g12yg9nh4ncma44emgm8msxe8aavzywt0p95tanv", Founder: false}, Admin: false, Finance: false}, {Member: memba_weighted_policy.Member{PersonID: "mikecito", Address: "g1cvr48r7l7lkmvp77cr6zg2zhu26jgfwr0y8pew", Founder: false}, Admin: false, Finance: false}, {Member: memba_weighted_policy.Member{PersonID: "david", Address: "g1rayfgklwl0aspz488wvrcrvt7t2quy6q06lgk2", Founder: false}, Admin: false, Finance: false}, {Member: memba_weighted_policy.Member{PersonID: "lours", Address: "g1nvxz94ukmggfx4mlldwae3cpde99qmldtcgm9u", Founder: false}, Admin: false, Finance: false}, {Member: memba_weighted_policy.Member{PersonID: "dadidou", Address: "g1jjeuv48j3pmsmnvga8jwfnc2amfyv9c30zx04y", Founder: false}, Admin: false, Finance: false}, }, memba_weighted_host.ApplicationPolicies{Market:marketPolicy, Reviews:reviewsPolicy, Quest:questPolicy, Arcade:arcadePolicy, Appstore:appstorePolicy, Escrow:escrowPolicy, Badges:badgesPolicy, Feed:feedPolicy, Channels:channelsPolicy, Feedback:feedbackPolicy}, cur) } func ProposeRole(cur realm, target address, role string, grant bool) uint64 { return host.ProposeRole(target, memba_weighted_host.Role(role), grant, cur) } func ProposeRecovery(cur realm, personID string, oldAddress, newAddress address) uint64 { return host.ProposeRecovery(personID, oldAddress, newAddress, cur) } func Vote(cur realm, id uint64, vote string) { host.Vote(id, memba_weighted_policy.Vote(vote), cur) } func Execute(cur realm, id uint64) { if host.Proposal(id).Feedback { executeFeedback(cur, id); return }; if host.Proposal(id).Channels { executeChannels(cur, id); return }; if host.Proposal(id).Feed { executeFeed(cur, id); return }; if host.Proposal(id).Badges { executeBadges(cur, id); return }; if host.Proposal(id).Escrow { executeEscrow(cur, id); return }; if host.Proposal(id).Appstore { executeAppstore(cur, id); return }; if host.Proposal(id).Arcade { executeArcade(cur, id); return }; if host.Proposal(id).Quest { executeQuest(cur, id); return }; if host.Proposal(id).Reviews { executeReviews(cur, id); return } if host.Proposal(id).Market { executeMarket(cur, id) } else { host.Execute(id, cur) } } func GetConfigJSON() string { return host.ConfigJSON() } func GetMembersJSON() string { return host.MembersJSON() } func GetProposalJSON(id uint64) string { return host.ProposalJSON(id) } func GetProposalsJSON(before uint64, limit int) string { return host.ProposalsJSON(before, limit) } func GetBallotJSON(proposalID string, voter address) string { return host.BallotJSON(proposalID, voter) } func GetPendingVotesJSON(voter address, before string, limit int) string { return host.PendingVotesJSON(voter, before, limit) } func Render(path string) string { return "# Memba DAO\n\n## Members (7)\n\nOne founder with 2 voting points and six equal core developers with 1 point each.\n\nRole changes and member-key recovery require 6 points and at least 4 people after 24 hours, or 5 core developers after 72 hours. Voting closes after 7 days; qualified proposals retain their execution delay.\n\nFixed governance of market config, reviews, quests, arcade, App Store, escrow, badges, feed, channels and feedback is available. A return proposal only stages the configured successor; separate acceptance is required. DAO state migration and treasury spending are not enabled." }
  22. #22quest_adapter.gno
  23. #23// Closed, fixed-target quest authority adapter. Never recover dispatch failures. package memba_dao import ( "gno.land/p/samcrew/memba_weighted_host" "gno.land/r/samcrew/memba_quest_attestation_v1" ) func questState() memba_weighted_host.QuestState { return memba_weighted_host.QuestState{Owner:address(memba_quest_attestation_v1.GetOwner()),PendingOwner:address(memba_quest_attestation_v1.GetPendingOwner()),Signer:memba_quest_attestation_v1.GetSigner()} } func ProposeQuestAccept(cur realm) uint64 { return host.ProposeQuest(questPolicy.Accept(),questState(),cur) } func ProposeQuestSigner(cur realm, key string) uint64 { return host.ProposeQuest(memba_weighted_host.QuestSigner(key),questState(),cur) } func ProposeQuestReturn(cur realm) uint64 { return host.ProposeQuest(questPolicy.Return(),questState(),cur) } func ProposeQuestAbortReturn(cur realm) uint64 { return host.ProposeQuest(questPolicy.AbortReturn(),questState(),cur) } func executeQuest(cur realm,id uint64) { before:=questState();a:=host.ConsumeQuest(id,before,cur);expected:=before switch a.Kind() { case memba_weighted_host.QuestAcceptOwner: expected.Owner=questPolicy.DAO();expected.PendingOwner="";memba_quest_attestation_v1.AcceptOwnership(cross(cur)) case memba_weighted_host.QuestSetSigner: expected.Signer=a.Key();memba_quest_attestation_v1.SetSigner(cross(cur),a.Key()) case memba_weighted_host.QuestReturnOwner: expected.PendingOwner=a.Recipient();memba_quest_attestation_v1.TransferOwnership(cross(cur),a.Recipient()) case memba_weighted_host.QuestAbortReturn: expected.PendingOwner="";memba_quest_attestation_v1.CancelOwnershipTransfer(cross(cur)) default:panic("unsupported quest action") } if questState()!=expected { panic("quest postcondition mismatch") } }
  24. #24reviews_adapter.gno

Result log

msg:0,success:true,log:,events:[]

← Back to block 315,078