Sui.

Publicación

Comparte tu conocimiento.

Bekky.
Jul 17, 2025
P&R expertos

Mejores prácticas para implementar cronogramas de adjudicación de derechos en Sui

Estoy diseñando un sistema de transferencia de fichas (por ejemplo, para asignar equipos o bloquear a inversores) en Sui Move y necesito asegurarme de que:

Seguridad: sin retiros prematuros

Flexibilidad: soporte para acantilados, colocación lineal o gradual

Eficiencia del gas: costos mínimos de almacenamiento

Transparencia: fácil verificación del estado de concesión

Desafíos actuales:

  • Los bloqueos de tiempo básicos funcionan pero carecen de un control granular
  • ¿Tiene problemas con la administración de múltiples destinatarios
  • ¿No estás seguro de cómo gestionar los casos de despido anticipado

Preguntas:

¿Cuál es la arquitectura más segura para la adjudicación de contratos?

¿Cómo implementar diferentes curvas de adjudicación (lineales, graduadas, en pendiente)?

¿Cuál es la mejor manera de gestionar los plazos revocables frente a los irrevocables?

¿Vulnerabilidades comunes que se deben evitar?

  • Sui
  • Move
0
1
Cuota
Comentarios
.

Respuestas

1
Evgeniy CRYPTOCOIN.
Jul 17 2025, 13:24

####** 1. Arquitectura Core Vesting**

#####Implementación mínima viable

module vesting::linear {  
    use sui::coin;  
    use sui::clock;  
    use sui::balance;  
    use sui::tx_context;  

    struct VestingSchedule has key {  
        id: UID,  
        recipient: address,  
        total_amount: u64,  
        start_time: u64,  // Clock timestamp  
        duration_ms: u64, // Total vesting period  
        claimed: u64  
    }  

    /// Initialize vesting  
    public entry fn create(  
        recipient: address,  
        total_amount: u64,  
        duration_ms: u64,  
        clock: &Clock,  
        ctx: &mut TxContext  
    ) {  
        let schedule = VestingSchedule {  
            id: object::new(ctx),  
            recipient,  
            total_amount,  
            start_time: clock.timestamp_ms,  
            duration_ms,  
            claimed: 0  
        };  
        transfer::transfer(schedule, recipient);  
    }  
}  

Componentes clave:

  • Clockmarcas de tiempo basadas en - (no números de bloque)
  • Objetos de programación autocustodiados
  • Adquisición lineal por defecto

2. Patrones avanzados de conferencia*

#####Acantilado + Revestimiento lineal

public fun claimable_amount(  
    schedule: &VestingSchedule,  
    clock: &Clock  
): u64 {  
    let elapsed = clock.timestamp_ms.saturating_sub(schedule.start_time);  

    // Cliff period (e.g., 1 year)  
    if (elapsed < CLIFF_MS) return 0;  

    // Linear vesting after cliff  
    let vested = (schedule.total_amount * elapsed) / schedule.duration_ms;  
    vested - schedule.claimed  
}  

#####Adquisición gradual (varios hitos)

struct GradedVesting has key {  
    id: UID,  
    milestones: vector<Milestone>, // [{time: u64, percent: u8}]  
    claimed: u64  
}  

public fun graded_claimable(schedule: &GradedVesting, clock: &Clock): u64 {  
    let total_vested = 0;  
    let i = 0;  
    while (i < vector::length(&schedule.milestones)) {  
        let milestone = vector::borrow(&schedule.milestones, i);  
        if (clock.timestamp_ms >= milestone.time) {  
            total_vested = total_vested +  
                (schedule.total_amount * milestone.percent as u64) / 100;  
        };  
        i = i + 1;  
    };  
    total_vested - schedule.claimed  
}  

####3. Mejoras de seguridad

#####Adhesión revocable (controles de administración)

struct AdminCap has key { id: UID }  

public entry fn revoke(  
    schedule: VestingSchedule,  
    admin_cap: &AdminCap,  
    ctx: &mut TxContext  
) {  
    assert!(address_of(signer) == admin_cap.admin, EUnauthorized);  
    let remaining = schedule.total_amount - schedule.claimed;  
    coin::transfer(remaining, admin_cap.admin, ctx);  
    object::delete(schedule);  
}  

#####Antifrontrunning

public entry fn claim(  
    schedule: &mut VestingSchedule,  
    clock: &Clock,  
    ctx: &mut TxContext  
) {  
    let amount = claimable_amount(schedule, clock);  
    assert!(amount > 0, ENothingToClaim);  
    assert!(tx_context::epoch(ctx) == clock.epoch(), EStaleClock);  

    schedule.claimed = schedule.claimed + amount;  
    transfer::public_transfer(coin::mint(amount, ctx), schedule.recipient);  
}  

####4. Técnicas de optimización de gas

#####Cronogramas de adquisición de lotes

struct BatchVesting has key {  
    id: UID,  
    schedules: Table<address, VestingSchedule>  
}  

// Claim all eligible in one TXN  
public entry fn batch_claim(batch: &mut BatchVesting, clock: &Clock) {  
    let iter = table::iter(&mut batch.schedules);  
    while (table::has_next(&iter)) {  
        let (addr, schedule) = table::next(&iter);  
        let amount = claimable_amount(schedule, clock);  
        if (amount > 0) transfer_coins(addr, amount);  
    }  
}  

#####Reembolsos de almacenamiento

// Use small types where possible  
struct CompactVesting {  
    start_time: u64,  
    duration_ms: u32, // Sufficient for 49-day periods  
    claimed: u64  
}  

####5. Vulnerabilidades comunes

Time Oracle ataca a Oráculo

// UNSAFE: Trusting user-provided timestamps  
fun unsafe_claim(user_time: u64) { ... }  

Errores de redondeo

// May leave "dust" unclaimed  
let vested = (amount * elapsed) / duration; // Use checked_math  

Falta la lógica de revocación

// Irrevocable vesting may violate securities laws  
struct DangerousVesting { ... }  

6. Estrategias de prueba*

#####Simulacro de prueba de reloj

#[test]  
fun test_cliff_period() {  
    let clock = mock_clock(0);  
    let schedule = create_vesting(CLIFF_MS * 2);  

    // Before cliff  
    test_clock::advance(&mut clock, CLIFF_MS - 1);  
    assert!(claimable(&schedule, &clock) == 0, ETestFail);  

    // After cliff  
    test_clock::advance(&mut clock, 1);  
    assert!(claimable(...) > 0, ETestFail);  
}  

#####Prueba de fuzz

#[test]  
fun test_overflow_scenarios() {  
    let schedule = VestingSchedule {  
        start_time: u64::MAX - 1000,  
        duration_ms: 2000  
    };  
    // Should handle wrap-around correctly  
    claimable_amount(&schedule, &clock);  
}  
0
Comentarios
.

Sabes la respuesta?

Inicie sesión y compártalo.

Sui is a Layer 1 protocol blockchain designed as the first internet-scale programmable blockchain platform.

431Publicaciones636Respuestas
Sui.X.Peera.

Gana tu parte de 1000 Sui

Gana puntos de reputación y obtén recompensas por ayudar a crecer a la comunidad de Sui.

Campaña de RecompensasJulio